ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/Storable.pm
Revision: 1.29
Committed: Wed Sep 24 21:31:29 2008 UTC (15 years, 9 months ago) by root
Branch: MAIN
Changes since 1.28: +10 -12 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.22 use strict qw(subs vars);
74 root 1.13 no warnings;
75 root 1.1
76     use Coro ();
77 root 1.2 use Coro::Semaphore ();
78 root 1.1
79 root 1.13 BEGIN {
80     # suppress warnings
81     local $^W = 0;
82     require Storable;
83     }
84    
85 root 1.1 use Storable;
86     use base "Exporter";
87    
88 root 1.26 our $VERSION = 4.748;
89 root 1.9 our @EXPORT = qw(thaw freeze nfreeze blocking_thaw blocking_freeze blocking_nfreeze);
90 root 1.1
91 root 1.29 our $GRANULARITY = 0.01;
92 root 1.28
93 root 1.2 my $lock = new Coro::Semaphore;
94    
95 root 1.8 sub guard {
96     $lock->guard
97     }
98    
99 root 1.22 # wrap xs functions
100 root 1.26 for (qw(net_pstore pstore net_mstore mstore pretrieve mretrieve dclone)) {
101 root 1.22 my $orig = \&{"Storable::$_"};
102     *{"Storable::$_"} = sub {
103     my $guard = $lock->guard;
104     &$orig
105     };
106     die if $@;
107     }
108    
109 root 1.6 sub thaw($) {
110 root 1.28 open my $fh, "<:cede($GRANULARITY)", \$_[0]
111     or die "cannot open pst via PerlIO::cede: $!";
112 root 1.6 Storable::fd_retrieve $fh
113     }
114    
115 root 1.1 sub freeze($) {
116 root 1.28 open my $fh, ">:cede($GRANULARITY)", \my $buf
117     or die "cannot open pst via PerlIO::cede: $!";
118 root 1.6 Storable::store_fd $_[0], $fh;
119 root 1.1 $buf
120     }
121    
122 root 1.6 sub nfreeze($) {
123 root 1.28 open my $fh, ">:cede($GRANULARITY)", \my $buf
124     or die "cannot open pst via PerlIO::cede: $!";
125 root 1.6 Storable::nstore_fd $_[0], $fh;
126     $buf
127     }
128    
129 root 1.10 sub blocking_thaw($) {
130 root 1.9 open my $fh, "<", \$_[0]
131     or die "cannot open pst: $!";
132     Storable::fd_retrieve $fh
133     }
134    
135 root 1.10 sub blocking_freeze($) {
136 root 1.6 open my $fh, ">", \my $buf
137     or die "cannot open pst: $!";
138     Storable::store_fd $_[0], $fh;
139     close $fh;
140    
141     $buf
142     }
143    
144 root 1.10 sub blocking_nfreeze($) {
145 root 1.6 open my $fh, ">", \my $buf
146     or die "cannot open pst: $!";
147     Storable::nstore_fd $_[0], $fh;
148     close $fh;
149    
150     $buf
151 root 1.1 }
152    
153     1;
154    
155     =head1 AUTHOR
156    
157     Marc Lehmann <schmorp@schmorp.de>
158     http://home.schmorp.de/
159    
160     =cut
161    
162