File Coverage

blib/lib/Cache/FastMmap.pm
Criterion Covered Total %
statement 273 299 91.3
branch 121 176 68.7
condition 70 99 70.7
subroutine 31 34 91.1
pod 13 16 81.2
total 508 624 81.4


line stmt bran cond sub pod time code
1             package Cache::FastMmap;
2              
3             =head1 NAME
4              
5             Cache::FastMmap - Uses an mmap'ed file to act as a shared memory interprocess cache
6              
7             =head1 SYNOPSIS
8              
9             use Cache::FastMmap;
10              
11             # Uses vaguely sane defaults
12             $Cache = Cache::FastMmap->new();
13              
14             # $Value must be a reference...
15             $Cache->set($Key, $Value);
16             $Value = $Cache->get($Key);
17              
18             $Cache = Cache::FastMmap->new(raw_values => 1);
19              
20             # $Value can't be a reference...
21             $Cache->set($Key, $Value);
22             $Value = $Cache->get($Key);
23              
24             =head1 ABSTRACT
25              
26             A shared memory cache through an mmap'ed file. It's core is written
27             in C for performance. It uses fcntl locking to ensure multiple
28             processes can safely access the cache at the same time. It uses
29             a basic LRU algorithm to keep the most used entries in the cache.
30              
31             =head1 DESCRIPTION
32              
33             In multi-process environments (eg mod_perl, forking daemons, etc),
34             it's common to want to cache information, but have that cache
35             shared between processes. Many solutions already exist, and may
36             suit your situation better:
37              
38             =over 4
39              
40             =item *
41              
42             L - acts as a database, data is not automatically
43             expired, slow
44              
45             =item *
46              
47             L - hash implementation is broken, data is not automatically
48             expired, slow
49              
50             =item *
51              
52             L - lots of features, slow
53              
54             =item *
55              
56             L - lots of features, VERY slow. Uses
57             IPC::ShareLite which freeze/thaws ALL data at each read/write
58              
59             =item *
60              
61             L - use your favourite RDBMS. can perform well, need a
62             DB server running. very global. socket connection latency
63              
64             =item *
65              
66             L - similar to this module, in pure perl. slows down
67             with larger pages
68              
69             =item *
70              
71             L - very fast (data ends up mostly in shared memory
72             cache) but acts as a database overall, so data is not automatically
73             expired
74              
75             =back
76              
77             In the case I was working on, I needed:
78              
79             =over 4
80              
81             =item *
82              
83             Automatic expiry and space management
84              
85             =item *
86              
87             Very fast access to lots of small items
88              
89             =item *
90              
91             The ability to fetch/store many items in one go
92              
93             =back
94              
95             Which is why I developed this module. It tries to be quite
96             efficient through a number of means:
97              
98             =over 4
99              
100             =item *
101              
102             Core code is written in C for performance
103              
104             =item *
105              
106             It uses multiple pages within a file, and uses Fcntl to only lock
107             a page at a time to reduce contention when multiple processes access
108             the cache.
109              
110             =item *
111              
112             It uses a dual level hashing system (hash to find page, then hash
113             within each page to find a slot) to make most C calls O(1) and
114             fast
115              
116             =item *
117              
118             On each C, if there are slots and page space available, only
119             the slot has to be updated and the data written at the end of the used
120             data space. If either runs out, a re-organisation of the page is
121             performed to create new slots/space which is done in an efficient way
122              
123             =back
124              
125             The class also supports read-through, and write-back or write-through
126             callbacks to access the real data if it's not in the cache, meaning that
127             code like this:
128              
129             my $Value = $Cache->get($Key);
130             if (!defined $Value) {
131             $Value = $RealDataSource->get($Key);
132             $Cache->set($Key, $Value)
133             }
134              
135             Isn't required, you instead specify in the constructor:
136              
137             Cache::FastMmap->new(
138             ...
139             context => $RealDataSourceHandle,
140             read_cb => sub { $_[0]->get($_[1]) },
141             write_cb => sub { $_[0]->set($_[1], $_[2]) },
142             );
143              
144             And then:
145              
146             my $Value = $Cache->get($Key);
147              
148             $Cache->set($Key, $NewValue);
149              
150             Will just work and will be read/written to the underlying data source as
151             needed automatically.
152              
153             =head1 PERFORMANCE
154              
155             If you're storing relatively large and complex structures into
156             the cache, then you're limited by the speed of the Storable module.
157             If you're storing simple structures, or raw data, then
158             Cache::FastMmap has noticeable performance improvements.
159              
160             See L for some
161             comparisons to other modules.
162              
163             =head1 COMPATIBILITY
164              
165             Cache::FastMmap uses mmap to map a file as the shared cache space,
166             and fcntl to do page locking. This means it should work on most
167             UNIX like operating systems.
168              
169             Ash Berlin has written a Win32 layer using MapViewOfFile et al. to
170             provide support for Win32 platform.
171              
172             =head1 MEMORY SIZE
173              
174             Because Cache::FastMmap mmap's a shared file into your processes memory
175             space, this can make each process look quite large, even though it's just
176             mmap'd memory that's shared between all processes that use the cache,
177             and may even be swapped out if the cache is getting low usage.
178              
179             However, the OS will think your process is quite large, which might
180             mean you hit some BSD::Resource or 'ulimits' you set previously that you
181             thought were sane, but aren't anymore, so be aware.
182              
183             =head1 CACHE FILES AND OS ISSUES
184              
185             Because Cache::FastMmap uses an mmap'ed file, when you put values into
186             the cache, you are actually "dirtying" pages in memory that belong to
187             the cache file. Your OS will want to write those dirty pages back to
188             the file on the actual physical disk, but the rate it does that at is
189             very OS dependent.
190              
191             In Linux, you have some control over how the OS writes those pages
192             back using a number of parameters in /proc/sys/vm
193              
194             dirty_background_ratio
195             dirty_expire_centisecs
196             dirty_ratio
197             dirty_writeback_centisecs
198              
199             How you tune these depends heavily on your setup.
200              
201             As an interesting point, if you use a highmem linux kernel, a change
202             between 2.6.16 and 2.6.20 made the kernel flush memory a LOT more.
203             There's details in this kernel mailing list thread:
204             L
205              
206             In most cases, people are not actually concerned about the persistence
207             of data in the cache, and so are happy to disable writing of any cache
208             data back to disk at all. Baically what they want is an in memory only
209             shared cache. The best way to do that is to use a "tmpfs" filesystem
210             and put all cache files on there.
211              
212             For instance, all our machines have a /tmpfs mount point that we
213             create in /etc/fstab as:
214              
215             none /tmpfs tmpfs defaults,noatime,size=1000M 0 0
216              
217             And we put all our cache files on there. The tmpfs filesystem is smart
218             enough to only use memory as required by files actually on the tmpfs,
219             so making it 1G in size doesn't actually use 1G of memory, it only uses
220             as much as the cache files we put on it. In all cases, we ensure that
221             we never run out of real memory, so the cache files effectively act
222             just as named access points to shared memory.
223              
224             Some people have suggested using anonymous mmaped memory. Unfortunately
225             we need a file descriptor to do the fcntl locking on, so we'd have
226             to create a separate file on a filesystem somewhere anyway. It seems
227             easier to just create an explicit "tmpfs" filesystem.
228              
229             =head1 PAGE SIZE AND KEY/VALUE LIMITS
230              
231             To reduce lock contention, Cache::FastMmap breaks up the file
232             into pages. When you get/set a value, it hashes the key to get a page,
233             then locks that page, and uses a hash table within the page to
234             get/store the actual key/value pair.
235              
236             One consequence of this is that you cannot store values larger than
237             a page in the cache at all. Attempting to store values larger than
238             a page size will fail (the set() function will return false).
239              
240             Also keep in mind that each page has it's own hash table, and that we
241             store the key and value data of each item. So if you are expecting to
242             store large values and/or keys in the cache, you should use page sizes
243             that are definitely larger than your largest key + value size + a few
244             kbytes for the overhead.
245              
246             =head1 USAGE
247              
248             Because the cache uses shared memory through an mmap'd file, you have
249             to make sure each process connects up to the file. There's probably
250             two main ways to do this:
251              
252             =over 4
253              
254             =item *
255              
256             Create the cache in the parent process, and then when it forks, each
257             child will inherit the same file descriptor, mmap'ed memory, etc and
258             just work. This is the recommended way. (BEWARE: This only works under
259             UNIX as Win32 has no concept of forking)
260              
261             =item *
262              
263             Explicitly connect up in each forked child to the share file. In this
264             case, make sure the file already exists and the children connect with
265             init_file => 0 to avoid deleting the cache contents and possible
266             race corruption conditions. Also be careful that multiple children
267             may race to create the file at the same time, each overwriting and
268             corrupting content. Use a separate lock file if you must to ensure
269             only one child creates the file. (This is the only possible way under
270             Win32)
271              
272             =back
273              
274             The first way is usually the easiest. If you're using the cache in a
275             Net::Server based module, you'll want to open the cache in the
276             C, because that's executed before the fork, but after
277             the process ownership has changed and any chroot has been done.
278              
279             In mod_perl, just open the cache at the global level in the appropriate
280             module, which is executed as the server is starting and before it
281             starts forking children, but you'll probably want to chmod or chown
282             the file to the permissions of the apache process.
283              
284             =head1 METHODS
285              
286             =over 4
287              
288             =cut
289              
290             # Modules/Export/XSLoader {{{
291 17     17   268826 use 5.006;
  17         44  
292 17     17   64 use strict;
  17         20  
  17         300  
293 17     17   58 use warnings;
  17         26  
  17         389  
294 17     17   8587 use bytes;
  17         153  
  17         61  
295              
296             our $VERSION = '1.44';
297              
298             require XSLoader;
299             XSLoader::load('Cache::FastMmap', $VERSION);
300              
301             # Track currently live caches so we can cleanup in END {}
302             # if we have empty_on_exit set
303             our %LiveCaches;
304              
305 17     17   1043 use constant FC_ISDIRTY => 1;
  17         26  
  17         47778  
306             # }}}
307              
308             =item I
309              
310             Create a new Cache::FastMmap object.
311              
312             Basic global parameters are:
313              
314             =over 4
315              
316             =item * B
317              
318             File to mmap for sharing of data.
319             default on unix: /tmp/sharefile-$pid-$time-$random
320             default on windows: %TEMP%\sharefile-$pid-$time-$random
321              
322             =item * B
323              
324             Clear any existing values and re-initialise file. Useful to do in a
325             parent that forks off children to ensure that file is empty at the start
326             (default: 0)
327              
328             B This is quite important to do in the parent to ensure a
329             consistent file structure. The shared file is not perfectly transaction
330             safe, and so if a child is killed at the wrong instant, it might leave
331             the cache file in an inconsistent state.
332              
333             =item * B
334              
335             Store values as raw binary data rather than using Storable to free/thaw
336             data structures (default: 0)
337              
338             =item * B
339              
340             Compress the value (but not the key) before storing into the cache, using
341             the compression package identified by the value of the parameter. Supported
342             values are:
343              
344             'zlib' for 'Compress::Zlib'
345             'lz4' for 'Compress::LZ4'
346             'snappy' for 'Compress:Snappy'
347              
348             If this parameter has a value the module
349             will attempt to load the associated package and then use the API of that
350             package to compress data before storing in the cache, and uncompress it upon
351             retrieval from the cache. (default: undef)
352              
353             ( Note: Historically this module only supported a boolean value for the
354             `compress` parameter and defaulted to use Compress::Zlib. The note for the
355             old `compress` parameter stated: "Some initial testing shows that the
356             uncompressing tends to be very fast, though the compressing can be quite
357             slow, so it's probably best to use this option only if you know values in
358             the cache are long-lived and have a high hit rate."
359              
360             Comparable test results for the other compression tools are not yet available;
361             submission of benchmarks welcome. However, the documentation for the 'Snappy'
362             library (http://google.github.io/snappy/) states: For instance, compared to
363             the fastest mode of zlib, Snappy is an order of magnitude faster for most
364             inputs, but the resulting compressed files are anywhere from 20% to 100%
365             bigger. )
366              
367             =item * B
368              
369             Deprecated. Please use B, see above.
370              
371             =item * B
372              
373             Enable some basic statistics capturing. When enabled, every read to
374             the cache is counted, and every read to the cache that finds a value
375             in the cache is also counted. You can then retrieve these values
376             via the get_statistics() call. This causes every read action to
377             do a write on a page, which can cause some more IO, so it's
378             disabled by default. (default: 0)
379              
380             =item * B
381              
382             Maximum time to hold values in the cache in seconds. A value of 0
383             means does no explicit expiry time, and values are expired only based
384             on LRU usage. Can be expressed as 1m, 1h, 1d for minutes/hours/days
385             respectively. (default: 0)
386              
387             =back
388              
389             You may specify the cache size as:
390              
391             =over 4
392              
393             =item * B
394              
395             Size of cache. Can be expresses as 1k, 1m for kilobytes or megabytes
396             respectively. Automatically guesses page size/page count values.
397              
398             =back
399              
400             Or specify explicit page size/page count values. If none of these are
401             specified, the values page_size = 64k and num_pages = 89 are used.
402              
403             =over 4
404              
405             =item * B
406              
407             Size of each page. Must be a power of 2 between 4k and 1024k. If not,
408             is rounded to the nearest value.
409              
410             =item * B
411              
412             Number of pages. Should be a prime number for best hashing
413              
414             =back
415              
416             The cache allows the use of callbacks for reading/writing data to an
417             underlying data store.
418              
419             =over 4
420              
421             =item * B
422              
423             Opaque reference passed as the first parameter to any callback function
424             if specified
425              
426             =item * B
427              
428             Callback to read data from the underlying data store. Called as:
429              
430             $read_cb->($context, $Key)
431            
432             Should return the value to use. This value will be saved in the cache
433             for future retrievals. Return undef if there is no value for the
434             given key
435              
436             =item * B
437              
438             Callback to write data to the underlying data store.
439             Called as:
440              
441             $write_cb->($context, $Key, $Value, $ExpiryTime)
442            
443             In 'write_through' mode, it's always called as soon as a I
444             is called on the Cache::FastMmap class. In 'write_back' mode, it's
445             called when a value is expunged from the cache if it's been changed
446             by a I rather than read from the underlying store with the
447             I above.
448              
449             Note: Expired items do result in the I being
450             called if 'write_back' caching is enabled and the item has been
451             changed. You can check the $ExpiryTime against C if you only
452             want to write back values which aren't expired.
453              
454             Also remember that I may be called in a different process
455             to the one that placed the data in the cache in the first place
456              
457             =item * B
458              
459             Callback to delete data from the underlying data store. Called as:
460              
461             $delete_cb->($context, $Key)
462              
463             Called as soon as I is called on the Cache::FastMmap class
464              
465             =item * B
466              
467             If set to true, then if the I is called and it returns
468             undef to say nothing was found, then that information is stored
469             in the cache, so that next time a I is called on that
470             key, undef is returned immediately rather than again calling
471             the I
472              
473             =item * B
474              
475             Either 'write_back' or 'write_through'. (default: write_through)
476              
477             =item * B
478              
479             If you're using a callback function, then normally the cache is not
480             re-enterable, and attempting to call a get/set on the cache will
481             cause an error. By setting this to one, the cache will unlock any
482             pages before calling the callback. During the unlock time, other
483             processes may change data in current cache page, causing possible
484             unexpected effects. You shouldn't set this unless you know you
485             want to be able to recall to the cache within a callback.
486             (default: 0)
487              
488             =item * B
489              
490             When you have 'write_back' mode enabled, then
491             you really want to make sure all values from the cache are expunged
492             when your program exits so any changes are written back.
493              
494             The trick is that we only want to do this in the parent process,
495             we don't want any child processes to empty the cache when they exit.
496             So if you set this, it takes the PID via $$, and only calls
497             empty in the DESTROY method if $$ matches the pid we captured
498             at the start. (default: 0)
499              
500             =item * B
501              
502             Unlink the share file when the cache is destroyed.
503              
504             As with empty_on_exit, this will only unlink the file if the
505             DESTROY occurs in the same PID that the cache was created in
506             so that any forked children don't unlink the file.
507              
508             This value defaults to 1 if the share_file specified does
509             not already exist. If the share_file specified does already
510             exist, it defaults to 0.
511              
512             =item * B
513              
514             Sets an alarm(10) before each page is locked via fcntl(F_SETLKW) to catch
515             any deadlock. This used to be the default behaviour, but it's not really
516             needed in the default case and could clobber sub-second Time::HiRes
517             alarms setup by other code. Defaults to 0.
518              
519             =back
520              
521             =cut
522             sub new {
523 25     25 1 62167 my $Proto = shift;
524 25   33     154 my $Class = ref($Proto) || $Proto;
525              
526             # If first item is a hash ref, use it as arguments
527 25 50       177 my %Args = ref($_[0]) eq 'HASH' ? %{shift()} : @_;
  0         0  
528              
529 25         41 my $Self = {};
530 25         44 bless ($Self, $Class);
531              
532             # Work out cache file and whether to init
533 25         44 my $share_file = $Args{share_file};
534 25 50       67 if (!$share_file) {
535 25   50     135 my $tmp_dir = $ENV{TMPDIR} || "/tmp";
536 25   50     110 my $win_tmp_dir = $ENV{TEMP} || "c:\\";
537 25 50       118 $share_file = ($^O eq "MSWin32" ? "$win_tmp_dir\\sharefile" : "$tmp_dir/sharefile");
538 25         707 $share_file .= "-" . $$ . "-" . time . "-" . int(rand(100000));
539             }
540 25 50       76 !ref($share_file) || die "share_file argument was a reference";
541 25         100 $Self->{share_file} = $share_file;
542              
543 25 100       73 my $init_file = $Args{init_file} ? 1 : 0;
544 25 50       58 my $test_file = $Args{test_file} ? 1 : 0;
545 25 100       54 my $enable_stats = $Args{enable_stats} ? 1 : 0;
546 25 50       51 my $catch_deadlocks = $Args{catch_deadlocks} ? 1 : 0;
547              
548             # Worth out unlink default if not specified
549 25 50       61 if (!exists $Args{unlink_on_exit}) {
550 25 50       1780 $Args{unlink_on_exit} = -f($share_file) ? 0 : 1;
551             }
552              
553             # Storing raw/storable values?
554 25   100     115 my $raw_values = $Self->{raw_values} = int($Args{raw_values} || 0);
555              
556             # Need storable module if not using raw values
557 25 100       73 if (!$raw_values) {
558 5 50   6   426 eval "use Storable qw(freeze thaw); 1;"
  6         2527  
  6         9639  
  6         291  
559             || die "Could not load Storable module: $@";
560             }
561              
562             # Compress stored values?
563 25   100     132 my $compressor = $Args{compressor} || 0;
564              
565             # Also support legacy boolean argument which forced use of Compress::Zlib
566 25 100 100     125 $compressor ||= $Args{compress} ? 'zlib' : 0;
567              
568 25         118 my %known_compressors = (
569             zlib => 'Compress::Zlib',
570             lz4 => 'Compress::LZ4',
571             snappy => 'Compress::Snappy',
572             );
573              
574 25 100       65 if ( $compressor ) {
575 4 50       9 if ( ! $known_compressors{ $compressor } ) {
576 0         0 die "Unrecognized value >$compressor< for `compressor` parameter";
577             }
578 4         4 $compressor = $known_compressors{ $compressor };
579              
580 4 50       225 if ( ! eval "require $compressor;" ) {
581 0         0 die "Could not load compression package: $compressor : $@";
582             } else {
583             # LZ4 and Snappy use same API
584 4 50 33     22 if ($compressor eq 'Compress::LZ4' || $compressor eq 'Compress::Snappy') {
    50          
585 0         0 $Self->{compress} = $compressor->can("compress");
586 0         0 $Self->{uncompress} = $compressor->can("uncompress");
587             } elsif ($compressor eq 'Compress::Zlib') {
588 4         22 $Self->{compress} = $compressor->can("memGzip");
589             # (gunzip from tmp var: https://rt.cpan.org/Ticket/Display.html?id=72945)
590 4         9 my $uncompress = $compressor->can("memGunzip");
591 4     2   17 $Self->{uncompress} = sub { &$uncompress(my $Tmp = shift) };
  2         5  
592             }
593             }
594             }
595              
596             # If using empty_on_exit, need to track used caches
597 25   100     150 my $empty_on_exit = $Self->{empty_on_exit} = int($Args{empty_on_exit} || 0);
598            
599             # Need Scalar::Util::weaken to track open caches
600 25 100       79 if ($empty_on_exit) {
601 1 50       63 eval "use Scalar::Util qw(weaken); 1;"
602             || die "Could not load Scalar::Util module: $@";
603             }
604              
605             # Work out expiry time in seconds
606 25         110 my $expire_time = $Self->{expire_time} = parse_expire_time($Args{expire_time});
607              
608             # Function rounds to the nearest power of 2
609 25     25 0 171 sub RoundPow2 { return int(2 ** int(log($_[0])/log(2)) + 0.1); }
610              
611             # Work out cache size
612 25         44 my ($cache_size, $num_pages, $page_size);
613              
614 25         180 my %Sizes = (k => 1024, m => 1024*1024);
615 25 50       60 if ($cache_size = $Args{cache_size}) {
616 0 0       0 $cache_size *= $Sizes{lc($1)} if $cache_size =~ s/([km])$//i;
617              
618 0 0       0 if ($num_pages = $Args{num_pages}) {
619 0         0 $page_size = RoundPow2($cache_size / $num_pages);
620 0 0       0 $page_size = 4096 if $page_size < 4096;
621              
622             } else {
623 0   0     0 $page_size = $Args{page_size} || 65536;
624 0 0       0 $page_size *= $Sizes{lc($1)} if $page_size =~ s/([km])$//i;
625 0 0       0 $page_size = 4096 if $page_size < 4096;
626              
627             # Increase num_pages till we exceed
628 0         0 $num_pages = 89;
629 0 0       0 if ($num_pages * $page_size <= $cache_size) {
630 0         0 while ($num_pages * $page_size <= $cache_size) {
631 0         0 $num_pages = $num_pages * 2 + 1;
632             }
633             } else {
634 0         0 while ($num_pages * $page_size > $cache_size) {
635 0         0 $num_pages = int(($num_pages-1) / 2);
636             }
637 0         0 $num_pages = $num_pages * 2 + 1;
638             }
639              
640             }
641              
642             } else {
643 25         62 ($num_pages, $page_size) = @Args{qw(num_pages page_size)};
644 25   100     67 $num_pages ||= 89;
645 25   100     75 $page_size ||= 65536;
646 25 50       143 $page_size *= $Sizes{lc($1)} if $page_size =~ s/([km])$//i;
647 25         62 $page_size = RoundPow2($page_size);
648             }
649              
650 25         36 $cache_size = $num_pages * $page_size;
651 25         93 @$Self{qw(cache_size num_pages page_size)}
652             = ($cache_size, $num_pages, $page_size);
653              
654             # Number of slots to start in each page
655 25   50     207 my $start_slots = int($Args{start_slots} || 0) || 89;
656              
657             # Save read through/write back/write through details
658 25   100     102 my $write_back = ($Args{write_action} || 'write_through') eq 'write_back';
659             @$Self{qw(context read_cb write_cb delete_cb)}
660 25         111 = @Args{qw(context read_cb write_cb delete_cb)};
661             @$Self{qw(cache_not_found allow_recursive write_back)}
662 25         85 = (@Args{qw(cache_not_found allow_recursive)}, $write_back);
663             @$Self{qw(unlink_on_exit enable_stats)}
664 25         66 = (@Args{qw(unlink_on_exit)}, $enable_stats);
665              
666             # Save pid
667 25         57 $Self->{pid} = $$;
668              
669             # Initialise C cache code
670 25         106 my $Cache = fc_new();
671              
672 25         47 $Self->{Cache} = $Cache;
673              
674             # Setup cache parameters
675 25         223 fc_set_param($Cache, 'init_file', $init_file);
676 25         46 fc_set_param($Cache, 'init_file', $init_file);
677 25         49 fc_set_param($Cache, 'test_file', $test_file);
678 25         46 fc_set_param($Cache, 'page_size', $page_size);
679 25         55 fc_set_param($Cache, 'num_pages', $num_pages);
680 25         46 fc_set_param($Cache, 'expire_time', $expire_time);
681 25         42 fc_set_param($Cache, 'share_file', $share_file);
682 25         42 fc_set_param($Cache, 'start_slots', $start_slots);
683 25         52 fc_set_param($Cache, 'catch_deadlocks', $catch_deadlocks);
684 25         55 fc_set_param($Cache, 'enable_stats', $enable_stats);
685              
686             # And initialise it
687 25         1218756 fc_init($Cache);
688              
689             # Track cache if need to empty on exit
690 25 100       168 weaken($LiveCaches{ref($Self)} = $Self)
691             if $empty_on_exit;
692              
693             # All done, return PERL hash ref as class
694 25         265 return $Self;
695             }
696              
697             =item I
698              
699             Search cache for given Key. Returns undef if not found. If
700             I specified and not found, calls the callback to try
701             and find the value for the key, and if found (or 'cache_not_found'
702             is set), stores it into the cache and returns the found value.
703              
704             I<%Options> is optional, and is used by get_and_set() to control
705             the locking behaviour. For now, you should probably ignore it
706             unless you read the code to understand how it works
707              
708             =cut
709             sub get {
710 165778     165778 1 1393714 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
711              
712             # Hash value, lock page, read result
713 165778         232382 my ($HashPage, $HashSlot) = fc_hash($Cache, $_[1]);
714 165778         182711 my $Unlock = $Self->_lock_page($HashPage);
715 165777         362086 my ($Val, $Flags, $Found) = fc_read($Cache, $HashSlot, $_[1]);
716              
717             # Value not found, check underlying data store
718 165777 100 100     318416 if (!$Found && (my $read_cb = $Self->{read_cb})) {
719              
720             # Callback to read from underlying data store
721             # (unlock page first if we allow recursive calls
722 12723 100       15533 $Unlock = undef if $Self->{allow_recursive};
723 12723         9436 $Val = eval { $read_cb->($Self->{context}, $_[1]); };
  12723         16336  
724 12723         31273 my $Err = $@;
725 12723 100       16692 $Unlock = $Self->_lock_page($HashPage) if $Self->{allow_recursive};
726              
727             # Pass on any error
728 12723 100       14806 if ($Err) {
729 1         4 die $Err;
730             }
731              
732             # If we found it, or want to cache not-found, store back into our cache
733 12722 50 66     19420 if (defined $Val || $Self->{cache_not_found}) {
734              
735             # Are we doing writeback's? If so, need to mark as dirty in cache
736 12722         9543 my $write_back = $Self->{write_back};
737              
738             # If not using raw values, use freeze() to turn data
739 12722 100       15060 $Val = freeze(\$Val) if !$Self->{raw_values};
740 12722 50       14647 $Val = $Self->{compress}($Val) if $Self->{compress};
741              
742             # Get key/value len (we've got 'use bytes'), and do expunge check to
743             # create space if needed
744 12722 100       17175 my $KVLen = length($_[1]) + (defined($Val) ? length($Val) : 0);
745 12722         15147 $Self->_expunge_page(2, 1, $KVLen);
746              
747 12722         25804 fc_write($Cache, $HashSlot, $_[1], $Val, -1, 0);
748             }
749             }
750              
751             # Unlock page and return any found value
752             # Unlock is done only if we're not in the middle of a get_set() operation.
753 165776   66     214467 my $SkipUnlock = $_[2] && $_[2]->{skip_unlock};
754 165776 100       201009 $Unlock = undef unless $SkipUnlock;
755              
756             # If not using raw values, use thaw() to turn data back into object
757 165776 100 66     201210 $Val = $Self->{uncompress}($Val) if defined($Val) && $Self->{compress};
758 165776 100 100     417876 $Val = ${thaw($Val)} if defined($Val) && !$Self->{raw_values};
  99309         136305  
759              
760             # If explicitly asked to skip unlocking, we return the reference to the unlocker
761 165776 100       889204 return ($Val, $Unlock) if $SkipUnlock;
762              
763 145770         183382 return $Val;
764             }
765              
766             =item I
767              
768             Store specified key/value pair into cache
769              
770             I<%Options> is optional, and is used by get_and_set() to control
771             the locking behaviour. For now, you should probably ignore it
772             unless you read the code to understand how it works
773              
774             This method returns true if the value was stored in the cache,
775             false otherwise. See the PAGE SIZE AND KEY/VALUE LIMITS section
776             for more details.
777              
778             =cut
779             sub set {
780 40882     40882 1 11625507 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
781              
782             # If not using raw values, use freeze() to turn data
783 40882 100       61537 my $Val = $Self->{raw_values} ? $_[2] : freeze(\$_[2]);
784 40882 100       125555 $Val = $Self->{compress}($Val) if $Self->{compress};
785              
786             # Get opts, make compatible with Cache::Cache interface
787 40882 100       55653 my $Opts = defined($_[3]) ? (ref($_[3]) ? $_[3] : { expire_time => $_[3] }) : undef;
    100          
788 40882 100 66     68425 my $expire_seconds = defined($Opts && $Opts->{expire_time}) ? parse_expire_time($Opts->{expire_time}) : -1;
789              
790             # Hash value, lock page
791 40882         66536 my ($HashPage, $HashSlot) = fc_hash($Cache, $_[1]);
792              
793             # If skip_lock is passed, it's a *reference* to an existing lock we
794             # have to take and delete so we can cleanup below before calling
795             # the callback
796 40882   66     55615 my $Unlock = $Opts && $Opts->{skip_lock};
797 40882 100       41312 if ($Unlock) {
798 15006         19873 ($Unlock, $$Unlock) = ($$Unlock, undef);
799             } else {
800 25876         29376 $Unlock = $Self->_lock_page($HashPage);
801             }
802              
803             # Are we doing writeback's? If so, need to mark as dirty in cache
804 40882         38802 my $write_back = $Self->{write_back};
805              
806             # Get key/value len (we've got 'use bytes'), and do expunge check to
807             # create space if needed
808 40882 100       55657 my $KVLen = length($_[1]) + (defined($Val) ? length($Val) : 0);
809 40882         50683 $Self->_expunge_page(2, 1, $KVLen);
810              
811             # Now store into cache
812 40882 100       104905 my $DidStore = fc_write($Cache, $HashSlot, $_[1], $Val, $expire_seconds, $write_back ? FC_ISDIRTY : 0);
813              
814             # Unlock page
815 40882         30038 $Unlock = undef;
816              
817             # If we're doing write-through, or write-back and didn't get into cache,
818             # write back to the underlying store
819 40882 100 66     56585 if ((!$write_back || !$DidStore) && (my $write_cb = $Self->{write_cb})) {
      100        
820 3000         2164 eval { $write_cb->($Self->{context}, $_[1], $_[2]); };
  3000         4632  
821             }
822              
823 40882         62560 return $DidStore;
824             }
825              
826             =item I
827              
828             Atomically retrieve and set the value of a Key.
829              
830             The page is locked while retrieving the $Key and is unlocked only after
831             the value is set, thus guaranteeing the value does not change between
832             the get and set operations.
833              
834             $Sub is a reference to a subroutine that is called to calculate the
835             new value to store. $Sub gets $Key and the current value
836             as parameters, and
837             should return the new value to set in the cache for the given $Key.
838              
839             If the subroutine returns an empty list, no value is stored back
840             in the cache. This avoids updating the expiry time on an entry
841             if you want to do a "get if in cache, store if not present" type
842             callback.
843              
844             For example, to atomically increment a value in the cache, you
845             can just use:
846              
847             $Cache->get_and_set($Key, sub { return ++$_[1]; });
848              
849             In scalar context, the return value from this function is the *new* value
850             stored back into the cache.
851              
852             In list context, a two item array is returned; the new value stored
853             back into the cache and a boolean that's true if the value was stored
854             in the cache, false otherwise. See the PAGE SIZE AND KEY/VALUE LIMITS
855             section for more details.
856              
857             Notes:
858              
859             =over 4
860              
861             =item *
862              
863             Do not perform any get/set operations from the callback sub, as these
864             operations lock the page and you may end up with a dead lock!
865              
866             =item *
867              
868             If your sub does a die/throws an exception, the page will correctly
869             be unlocked (1.15 onwards)
870              
871             =back
872              
873             =cut
874             sub get_and_set {
875 15006     15006 1 71822 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
876              
877 15006         32263 my ($Value, $Unlock) = $Self->get($_[1], { skip_unlock => 1 });
878              
879             # If this throws an error, $Unlock ref will still unlock page
880 15006         33917 my @NewValue = $_[2]->($_[1], $Value);
881              
882 15006         41181 my $DidStore = 0;
883 15006 50       22366 if (@NewValue) {
884 15006         12037 ($Value) = @NewValue;
885 15006         34085 my $DidStore = $Self->set($_[1], $Value, { skip_lock => \$Unlock });
886             }
887              
888 15006 50       45490 return wantarray ? ($Value, $DidStore) : $Value;
889             }
890              
891             =item I
892              
893             Delete the given key from the cache
894              
895             I<%Options> is optional, and is used by get_and_remove() to control
896             the locking behaviour. For now, you should probably ignore it
897             unless you read the code to understand how it works
898              
899             =cut
900             sub remove {
901 11301     11301 1 29736 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
902              
903             # Hash value, lock page, read result
904 11301         15599 my ($HashPage, $HashSlot) = fc_hash($Cache, $_[1]);
905              
906             # If skip_lock is passed, it's a *reference* to an existing lock we
907             # have to take and delete so we can cleanup below before calling
908             # the callback
909 11301   66     16503 my $Unlock = $_[2] && $_[2]->{skip_lock};
910 11301 100       12553 if ($Unlock) {
911 5000         5573 ($Unlock, $$Unlock) = ($$Unlock, undef);
912             } else {
913 6301         7124 $Unlock = $Self->_lock_page($HashPage);
914             }
915              
916 11301         20961 my ($DidDel, $Flags) = fc_delete($Cache, $HashSlot, $_[1]);
917 11301         8655 $Unlock = undef;
918              
919             # If we deleted from the cache, and it's not dirty, also delete
920             # from underlying store
921 11301 100 66     13582 if ((!$DidDel || ($DidDel && !($Flags & FC_ISDIRTY)))
      100        
922             && (my $delete_cb = $Self->{delete_cb})) {
923 299         222 eval { $delete_cb->($Self->{context}, $_[1]); };
  299         324  
924             }
925            
926 11301         14375 return $DidDel;
927             }
928              
929             =item I
930              
931             Atomically retrieve value of a Key while removing it from the cache.
932              
933             The page is locked while retrieving the $Key and is unlocked only after
934             the value is removed, thus guaranteeing the value stored by someone else
935             isn't removed by us.
936              
937             =cut
938             sub get_and_remove {
939 5000     5000 1 11163 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
940              
941 5000         9236 my ($Value, $Unlock) = $Self->get($_[1], { skip_unlock => 1 });
942 5000         11134 my $DidDel = $Self->remove($_[1], { skip_lock => \$Unlock });
943 5000 50       11627 return wantarray ? ($Value, $DidDel) : $Value;
944             }
945              
946             =item I
947              
948             Clear all items from the cache
949              
950             Note: If you're using callbacks, this has no effect
951             on items in the underlying data store. No delete
952             callbacks are made
953              
954             =cut
955             sub clear {
956 3     3 1 1430 my $Self = shift;
957 3         11 $Self->_expunge_all(1, 0);
958             }
959              
960             =item I
961              
962             Clear all expired items from the cache
963              
964             Note: If you're using callbacks, this has no effect
965             on items in the underlying data store. No delete
966             callbacks are made, and no write callbacks are made
967             for the expired data
968              
969             =cut
970             sub purge {
971 0     0 1 0 my $Self = shift;
972 0         0 $Self->_expunge_all(0, 0);
973             }
974              
975             =item I
976              
977             Empty all items from the cache, or if $OnlyExpired is
978             true, only expired items.
979              
980             Note: If 'write_back' mode is enabled, any changed items
981             are written back to the underlying store. Expired items are
982             written back to the underlying store as well.
983              
984             =cut
985             sub empty {
986 5     5 1 1470 my $Self = shift;
987 5 50       29 $Self->_expunge_all($_[0] ? 0 : 1, 1);
988             }
989              
990             =item I
991              
992             Get a list of keys/values held in the cache. May immediately be out of
993             date because of the shared access nature of the cache
994              
995             If $Mode == 0, an array of keys is returned
996              
997             If $Mode == 1, then an array of hashrefs, with 'key',
998             'last_access', 'expire_time' and 'flags' keys is returned
999              
1000             If $Mode == 2, then hashrefs also contain 'value' key
1001              
1002             =cut
1003             sub get_keys {
1004 12     12 1 16857 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
1005              
1006 12   100     43 my $Mode = $_[1] || 0;
1007 12         25 my ($Compress, $RawValues) = @$Self{qw(compress raw_values)};
1008              
1009 12 100 66     3212 return fc_get_keys($Cache, $Mode)
      66        
      66        
1010             if $Mode <= 1 || ($Mode == 2 && $RawValues && !$Compress);
1011              
1012             # If we're getting values as well, and they're not raw, unfreeze them
1013 1         206 my @Details = fc_get_keys($Cache, 2);
1014              
1015 1         4 for (@Details) {
1016 2         3 my $Val = $_->{value};
1017 2 50       6 if (defined $Val) {
1018 2 50       3 $Val = $Self->{uncompress}($Val) if $Compress;
1019 2 50       4 if (!$RawValues) {
1020 2         2 $Val = eval { thaw($Val) };
  2         4  
1021 2 50       27 $Val = $$Val if ref($Val);
1022             }
1023 2         4 $_->{value} = $Val;
1024             }
1025             }
1026 1         3 return @Details;
1027             }
1028              
1029             =item I
1030              
1031             Returns a two value list of (nreads, nreadhits). This
1032             only works if you passed enable_stats in the constructor
1033              
1034             nreads is the total number of read attempts done on the
1035             cache since it was created
1036              
1037             nreadhits is the total number of read attempts done on
1038             the cache since it was created that found the key/value
1039             in the cache
1040              
1041             If $Clear is true, the values are reset immediately after
1042             they are retrieved
1043              
1044             =cut
1045             sub get_statistics {
1046 3     3 1 1847 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
1047 3         3 my $Clear = $_[1];
1048              
1049 3         4 my ($NReads, $NReadHits) = (0, 0);
1050 3         11 for (0 .. $Self->{num_pages}-1) {
1051 267         324 my $Unlock = $Self->_lock_page($_);
1052 267         337 my ($PNReads, $PNReadHits) = fc_get_page_details($Cache);
1053 267         198 $NReads += $PNReads;
1054 267         157 $NReadHits += $PNReadHits;
1055 267 100       415 fc_reset_page_details($Cache) if $Clear;
1056 267         309 $Unlock = undef;
1057             }
1058 3         8 return ($NReads, $NReadHits);
1059             }
1060              
1061             =item I
1062              
1063             The two multi_xxx routines act a bit differently to the
1064             other routines. With the multi_get, you pass a separate
1065             PageKey value and then multiple keys. The PageKey value
1066             is hashed, and that page locked. Then that page is
1067             searched for each key. It returns a hash ref of
1068             Key => Value items found in that page in the cache.
1069              
1070             The main advantage of this is just a speed one, if you
1071             happen to need to search for a lot of items on each call.
1072              
1073             For instance, say you have users and a bunch of pieces
1074             of separate information for each user. On a particular
1075             run, you need to retrieve a sub-set of that information
1076             for a user. You could do lots of get() calls, or you
1077             could use the 'username' as the page key, and just
1078             use one multi_get() and multi_set() call instead.
1079              
1080             A couple of things to note:
1081              
1082             =over 4
1083              
1084             =item 1.
1085              
1086             This makes multi_get()/multi_set() and get()/set()
1087             incompatible. Don't mix calls to the two, because
1088             you won't find the data you're expecting
1089              
1090             =item 2.
1091              
1092             The writeback and callback modes of operation do
1093             not work with multi_get()/multi_set(). Don't attempt
1094             to use them together.
1095              
1096             =back
1097              
1098             =cut
1099             sub multi_get {
1100 2     2 1 691 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
1101              
1102             # Hash value page key, lock page
1103 2         6 my ($HashPage, $HashSlot) = fc_hash($Cache, $_[1]);
1104 2         4 my $Unlock = $Self->_lock_page($HashPage);
1105              
1106             # For each key to find
1107 2         3 my ($Keys, %KVs) = ($_[2]);
1108 2         5 for (@$Keys) {
1109              
1110             # Hash key to get slot in this page and read
1111 4         6 my $FinalKey = "$_[1]-$_";
1112 4         8 (undef, $HashSlot) = fc_hash($Cache, $FinalKey);
1113 4         10 my ($Val, $Flags, $Found) = fc_read($Cache, $HashSlot, $FinalKey);
1114 4 50       8 next unless $Found;
1115              
1116             # If not using raw values, use thaw() to turn data back into object
1117 4 50 33     12 $Val = $Self->{uncompress}($Val) if defined($Val) && $Self->{compress};
1118 4 50 33     14 $Val = ${thaw($Val)} if defined($Val) && !$Self->{raw_values};
  0         0  
1119              
1120             # Save to return
1121 4         8 $KVs{$_} = $Val;
1122             }
1123              
1124             # Unlock page and return any found value
1125 2         2 $Unlock = undef;
1126              
1127 2         3 return \%KVs;
1128             }
1129              
1130             =item I $Value1, $Key2 => $Value2, ... }, [ \%Options ])>
1131              
1132             Store specified key/value pair into cache
1133              
1134             =cut
1135             sub multi_set {
1136 2     2 1 1757 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
1137              
1138             # Get opts, make compatible with Cache::Cache interface
1139 2 0       5 my $Opts = defined($_[3]) ? (ref($_[3]) ? $_[3] : { expire_time => $_[3] }) : undef;
    50          
1140 2 50 33     7 my $expire_seconds = defined($Opts && $Opts->{expire_time}) ? parse_expire_time($Opts->{expire_time}) : -1;
1141              
1142             # Hash page key value, lock page
1143 2         6 my ($HashPage, $HashSlot) = fc_hash($Cache, $_[1]);
1144 2         4 my $Unlock = $Self->_lock_page($HashPage);
1145              
1146             # Loop over each key/value storing into this page
1147 2         2 my $KVs = $_[2];
1148 2         10 while (my ($Key, $Val) = each %$KVs) {
1149              
1150             # If not using raw values, use freeze() to turn data
1151 4 50       6 $Val = freeze(\$Val) unless $Self->{raw_values};
1152 4 50       7 $Val = $Self->{compress}($Val) if $Self->{compress};
1153              
1154             # Get key/value len (we've got 'use bytes'), and do expunge check to
1155             # create space if needed
1156 4         32 my $FinalKey = "$_[1]-$Key";
1157 4         4 my $KVLen = length($FinalKey) + length($Val);
1158 4         5 $Self->_expunge_page(2, 1, $KVLen);
1159              
1160             # Now hash key and store into page
1161 4         7 (undef, $HashSlot) = fc_hash($Cache, $FinalKey);
1162 4         17 my $DidStore = fc_write($Cache, $HashSlot, $FinalKey, $Val, $expire_seconds, 0);
1163             }
1164              
1165             # Unlock page
1166 2         2 $Unlock = undef;
1167              
1168 2         3 return 1;
1169             }
1170              
1171             =back
1172              
1173             =cut
1174              
1175             =head1 INTERNAL METHODS
1176              
1177             =over 4
1178              
1179             =cut
1180              
1181             =item I<_expunge_all($Mode, $WB)>
1182              
1183             Expunge all items from the cache
1184              
1185             Expunged items (that have not expired) are written
1186             back to the underlying store if write_back is enabled
1187              
1188             =cut
1189             sub _expunge_all {
1190 8     8   24 my ($Self, $Cache, $Mode, $WB) = ($_[0], $_[0]->{Cache}, $_[1], $_[2]);
1191              
1192             # Repeat expunge for each page
1193 8         32 for (0 .. $Self->{num_pages}-1) {
1194 540         671 my $Unlock = $Self->_lock_page($_);
1195 540         705 $Self->_expunge_page($Mode, $WB, -1);
1196 540         1086 $Unlock = undef;
1197             }
1198              
1199             }
1200              
1201             =item I<_expunge_page($Mode, $WB, $Len)>
1202              
1203             Expunge items from the current page to make space for
1204             $Len bytes key/value items
1205              
1206             Expunged items (that have not expired) are written
1207             back to the underlying store if write_back is enabled
1208              
1209             =cut
1210             sub _expunge_page {
1211 54148     54148   87248 my ($Self, $Cache, $Mode, $WB, $Len) = ($_[0], $_[0]->{Cache}, @_[1 .. 3]);
1212              
1213             # If writeback mode, need to get expunged items to write back
1214 54148 100 100     121079 my $write_cb = $Self->{write_back} && $WB ? $Self->{write_cb} : undef;
1215              
1216 54148 100       146820 my @WBItems = fc_expunge($Cache, $Mode, $write_cb ? 1 : 0, $Len);
1217              
1218 54148         56595 my ($Compress, $RawValues) = @$Self{qw(compress raw_values)};
1219              
1220 54148         88432 for (@WBItems) {
1221 14147 100       33255 next if !($_->{flags} & FC_ISDIRTY);
1222              
1223 6102         4393 my $Val = $_->{value};
1224 6102 100       7067 if (defined $Val) {
1225 6101 50       6552 $Val = Compress::Zlib::memGunzip($Val) if $Compress;
1226 6101 100       7296 if (!$RawValues) {
1227 2         2 $Val = eval { thaw($Val) };
  2         4  
1228 2 50       23 $Val = $$Val if ref($Val);
1229             }
1230             }
1231 6102         4101 eval { $write_cb->($Self->{context}, $_->{key}, $Val, $_->{expire_time}); };
  6102         7742  
1232             }
1233             }
1234              
1235             =item I<_lock_page($Page)>
1236              
1237             Lock a given page in the cache, and return an object
1238             reference that when DESTROYed, unlocks the page
1239              
1240             =cut
1241             sub _lock_page {
1242 198767     198767   168036 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
1243             my $Unlock = Cache::FastMmap::OnLeave->new(sub {
1244 198767 100   198767   988493 fc_unlock($Cache) if fc_is_locked($Cache);
1245 198767         471485 });
1246 198767         1696311 fc_lock($Cache, $_[1]);
1247 198766         186825 return $Unlock;
1248             }
1249              
1250             sub parse_expire_time {
1251 42   100 42 0 162 my $expire_time = shift || '';
1252 42 100       165 return 1 if $expire_time eq 'now';
1253 40 100       94 return 0 if $expire_time eq 'never';
1254 38         190 my %Times = ('' => 1, s => 1, m => 60, h => 60*60, d => 24*60*60, w => 7*24*60*60);
1255 38 100       238 return $expire_time =~ /^(\d+)\s*([mhdws]?)/i ? $1 * $Times{lc($2)} : 0;
1256             }
1257              
1258             sub cleanup {
1259 23     23 0 59 my ($Self, $Cache) = ($_[0], $_[0]->{Cache});
1260              
1261             # Avoid potential double cleanup
1262 23 50       106 return if $Self->{cleaned};
1263 23         48 $Self->{cleaned} = 1;
1264              
1265             # Expunge all entries on exit if requested and in parent process
1266 23 50 66     152 if ($Self->{empty_on_exit} && $Cache && $Self->{pid} == $$) {
      66        
1267 1         3 $Self->empty();
1268             }
1269              
1270 23 50       122 if ($Cache) {
1271 23         1068 fc_close($Cache);
1272 23         45 $Cache = undef;
1273 23         76 delete $Self->{Cache};
1274             }
1275              
1276             unlink($Self->{share_file})
1277 23 100 66     13762 if $Self->{unlink_on_exit} && $Self->{pid} == $$;
1278              
1279             }
1280              
1281             sub DESTROY {
1282 23     23   155911 my $Self = shift;
1283 23         95 $Self->cleanup();
1284 23 100       1934 delete $LiveCaches{ref($Self)} if $Self->{empty_on_exit};
1285             }
1286              
1287             sub END {
1288 17     17   18519 while (my (undef, $Self) = each %LiveCaches) {
1289             # Weak reference, might be undef already
1290 0 0       0 $Self->cleanup() if $Self;
1291             }
1292 17         121 %LiveCaches = ();
1293             }
1294              
1295             sub CLONE {
1296 0     0   0 die "Cache::FastMmap does not support threads sorry";
1297             }
1298              
1299             1;
1300              
1301             package Cache::FastMmap::OnLeave;
1302 17     17   90 use strict;
  17         27  
  17         1687  
1303              
1304             sub new {
1305 198767     198767   157419 my $Class = shift;
1306 198767         147823 my $Ref = \$_[0];
1307 198767         178638 bless $Ref, $Class;
1308 198767         187915 return $Ref;
1309             }
1310              
1311             sub disable {
1312 0     0   0 ${$_[0]} = undef;
  0         0  
1313             }
1314              
1315             sub DESTROY {
1316 198767     198767   143343 my $e = $@; # Save errors from code calling us
1317 198767         128693 eval {
1318              
1319 198767         135067 my $Ref = shift;
1320 198767 50       323385 $$Ref->() if $$Ref;
1321              
1322             };
1323             # $e .= " (in cleanup) $@" if $@;
1324 198767         803786 $@ = $e;
1325             }
1326              
1327             1;
1328              
1329             __END__