1=head1 NAME 2 3Coro::Storable - offer a more fine-grained Storable interface 4 5=head1 SYNOPSIS 6 7 use Coro::Storable; 8 9=head1 DESCRIPTION 10 11This module implements a few functions from the Storable module in a way 12so that it cede's more often. Some applications (such as the Deliantra 13game server) sometimes need to load large Storable objects without 14blocking the server for a long time. 15 16This is being implemented by using a perlio layer that feeds only small 17amounts of data (4096 bytes per call) into Storable, and C<Coro::cede>'ing 18regularly (at most 100 times per second by default, though). 19 20As Storable is not reentrant, this module also wraps most functions of the 21Storable module so that only one freeze or thaw is done at any one moment 22(and recursive invocations are not currently supported). 23 24=head1 FUNCTIONS 25 26=over 4 27 28=item $ref = thaw $pst 29 30Retrieve an object from the given $pst, which must have been created with 31C<Coro::Storable::freeze> or C<Storable::store_fd>/C<Storable::store> 32(sorry, but Storable uses incompatible formats for disk/mem objects). 33 34This function will cede regularly. 35 36=item $pst = freeze $ref 37 38Freeze the given scalar into a Storable object. It uses the same format as 39C<Storable::store_fd>. 40 41This functino will cede regularly. 42 43=item $pst = nfreeze $ref 44 45Same as C<freeze> but is compatible to C<Storable::nstore_fd> (note the 46C<n>). 47 48=item $pst = blocking_freeze $ref 49 50Same as C<freeze> but is guaranteed to block. This is useful e.g. in 51C<Coro::Util::fork_eval> when you want to serialise a data structure 52for use with the C<thaw> function for this module. You cannot use 53C<Storable::freeze> for this as Storable uses incompatible formats for 54memory and file images, and this module uses file images. 55 56=item $pst = blocking_nfreeze $ref 57 58Same as C<blocking_freeze> but uses C<nfreeze> internally. 59 60=item $guard = guard 61 62Acquire the Storable lock, for when you want to call Storable yourself. 63 64Note that this module already wraps all Storable functions, so there is 65rarely the need to do this yourself. 66 67=back 68 69=cut 70 71package Coro::Storable; 72 73use common::sense; 74 75use Coro (); 76use Coro::Semaphore (); 77 78BEGIN { 79 # suppress warnings 80 local $^W = 0; 81 require Storable; 82} 83 84use Storable; 85use base "Exporter"; 86 87our $VERSION = 6.57; 88our @EXPORT = qw(thaw freeze nfreeze blocking_thaw blocking_freeze blocking_nfreeze); 89 90our $GRANULARITY = 0.01; 91 92my $lock = new Coro::Semaphore; 93 94sub guard { 95 $lock->guard 96} 97 98# wrap xs functions 99for (qw(net_pstore pstore net_mstore mstore pretrieve mretrieve dclone)) { 100 my $orig = \&{"Storable::$_"}; 101 *{"Storable::$_"} = eval 'sub (' . (prototype $orig) . ') { 102 my $guard = $lock->guard; 103 &$orig 104 }'; 105 die if $@; 106} 107 108sub thaw($) { 109 open my $fh, "<:cede($GRANULARITY)", \$_[0] 110 or die "cannot open pst via PerlIO::cede: $!"; 111 Storable::fd_retrieve $fh 112} 113 114sub freeze($) { 115 open my $fh, ">:cede($GRANULARITY)", \my $buf 116 or die "cannot open pst via PerlIO::cede: $!"; 117 Storable::store_fd $_[0], $fh; 118 close $fh; 119 120 $buf 121} 122 123sub nfreeze($) { 124 open my $fh, ">:cede($GRANULARITY)", \my $buf 125 or die "cannot open pst via PerlIO::cede: $!"; 126 Storable::nstore_fd $_[0], $fh; 127 close $fh; 128 129 $buf 130} 131 132sub blocking_thaw($) { 133 open my $fh, "<", \$_[0] 134 or die "cannot open pst: $!"; 135 Storable::fd_retrieve $fh 136} 137 138sub blocking_freeze($) { 139 open my $fh, ">", \my $buf 140 or die "cannot open pst: $!"; 141 Storable::store_fd $_[0], $fh; 142 close $fh; 143 144 $buf 145} 146 147sub blocking_nfreeze($) { 148 open my $fh, ">", \my $buf 149 or die "cannot open pst: $!"; 150 Storable::nstore_fd $_[0], $fh; 151 close $fh; 152 153 $buf 154} 155 1561; 157 158=head1 AUTHOR/SUPPORT/CONTACT 159 160 Marc A. Lehmann <schmorp@schmorp.de> 161 http://software.schmorp.de/pkg/Coro.html 162 163=cut 164 165 166