ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/Storable.pm
Revision: 1.68
Committed: Wed Aug 3 14:52:20 2011 UTC (12 years, 10 months ago) by root
Branch: MAIN
CVS Tags: rel-6_04
Changes since 1.67: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

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