ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/Storable.pm
Revision: 1.40
Committed: Thu Nov 20 09:37:21 2008 UTC (15 years, 6 months ago) by root
Branch: MAIN
CVS Tags: rel-5_0
Changes since 1.39: +1 -1 lines
Log Message:
5.0

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.40 our $VERSION = "5.0";
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.30 close $fh;
120    
121 root 1.1 $buf
122     }
123    
124 root 1.6 sub nfreeze($) {
125 root 1.28 open my $fh, ">:cede($GRANULARITY)", \my $buf
126     or die "cannot open pst via PerlIO::cede: $!";
127 root 1.6 Storable::nstore_fd $_[0], $fh;
128 root 1.30 close $fh;
129    
130 root 1.6 $buf
131     }
132    
133 root 1.10 sub blocking_thaw($) {
134 root 1.9 open my $fh, "<", \$_[0]
135     or die "cannot open pst: $!";
136     Storable::fd_retrieve $fh
137     }
138    
139 root 1.10 sub blocking_freeze($) {
140 root 1.6 open my $fh, ">", \my $buf
141     or die "cannot open pst: $!";
142     Storable::store_fd $_[0], $fh;
143     close $fh;
144    
145     $buf
146     }
147    
148 root 1.10 sub blocking_nfreeze($) {
149 root 1.6 open my $fh, ">", \my $buf
150     or die "cannot open pst: $!";
151     Storable::nstore_fd $_[0], $fh;
152     close $fh;
153    
154     $buf
155 root 1.1 }
156    
157     1;
158    
159     =head1 AUTHOR
160    
161     Marc Lehmann <schmorp@schmorp.de>
162     http://home.schmorp.de/
163    
164     =cut
165    
166