ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/Storable.pm
Revision: 1.3
Committed: Wed Apr 18 13:46:32 2007 UTC (17 years, 1 month ago) by root
Branch: MAIN
Changes since 1.2: +2 -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     so that it cede's more often. Some applications (such as the Crossfire
13     game server) sometimes need to load large Storable objects without
14     blocking the server for a long time.
15    
16 root 1.2 As it seems that Storable is not reentrant, this module also serialises
17     calls to freeze and thaw between coroutines.
18    
19 root 1.1 =head1 FUNCTIONS
20    
21     =over 4
22    
23     =item $ref = thaw $pst
24    
25     Retrieve an object from the given $pst, which must have been created with
26     C<Coro::Storable::freeze> or C<Storable::store_fd>/C<Storable::store>
27     (sorry, but Storable uses incompatible formats for disk/mem objects).
28    
29     This works by calling C<Coro::cede> for every 512 bytes read in.
30    
31     =item $pst = freeze $ref
32    
33     Freeze the given scalar into a Storable object. It uses the same format as
34     C<Storable::nstore_fd> (note the C<n>).
35    
36     This works by calling C<Coro::cede> for every write that Storable
37     issues. Unfortunately, Storable often makes many very small writes, so it
38     is rather inefficient. But it does keep the latency low.
39    
40     =back
41    
42     =cut
43    
44     package Coro::Storable;
45    
46     use strict;
47    
48     use Coro ();
49 root 1.2 use Coro::Semaphore ();
50 root 1.1
51     use Storable;
52     use base "Exporter";
53    
54     our $VERSION = '0.1';
55     our @EXPORT = qw(freeze thaw);
56    
57 root 1.2 my $lock = new Coro::Semaphore;
58    
59 root 1.1 sub freeze($) {
60 root 1.2 my $guard = $lock->guard;
61    
62 root 1.1 open my $fh, ">:via(CoroCede)", \my $buf
63     or die "cannot open pst via CoroCede: $!";
64     Storable::nstore_fd $_[0], $fh;
65     $buf
66     }
67    
68     sub thaw($) {
69 root 1.2 my $guard = $lock->guard;
70    
71 root 1.1 open my $fh, "<:via(CoroCede)", \$_[0]
72     or die "cannot open pst via CoroCede: $!";
73     Storable::fd_retrieve $fh
74     }
75    
76     package PerlIO::via::CoroCede;
77    
78     # generic cede-on-read/write filtering layer
79    
80     sub PUSHED {
81     __PACKAGE__
82     }
83    
84     sub FILL {
85     Coro::cede;
86 root 1.3 read $_[1], my $buf, 512
87     or return undef;
88 root 1.1 $buf
89     }
90    
91     sub WRITE {
92     Coro::cede;
93     (print {$_[2]} $_[1]) ? length $_[1] : -1
94     }
95    
96     1;
97    
98     =head1 AUTHOR
99    
100     Marc Lehmann <schmorp@schmorp.de>
101     http://home.schmorp.de/
102    
103     =cut
104    
105