Skip Menu |

This queue is for tickets about the Cache-FastMmap CPAN distribution.

Report information
The Basics
Id: 61405
Status: resolved
Priority: 0/
Queue: Cache-FastMmap

People
Owner: Nobody in particular
Requestors: j.david.lowe [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: mmc_lock_page() clobbers high-resolution alarm
When a high-resolution alarm (ualarm or setitimer) is set outside of Cache::FastMmap, the current implementation of mmc_lock_page() clobbers its value. I'm using Cache::FastMmap in an environment that needs sub-second timeout controls, so this is a problem for me. Here's the test case: #!/usr/bin/env perl use strict; use warnings; use Cache::FastMmap (); use File::Temp (); use Time::HiRes (); use Test::More qw(no_plan); my $share_file = File::Temp::tmpnam(); my $c = new Cache::FastMmap( init_file => 1, share_file => $share_file, page_size => 65536, num_pages => 89, raw_values => 1, compress => 0, enable_stats => 0, expire_time => 0, unlink_on_exit => 0, empty_on_exit => 0, ); $c->set('foo', 'bar'); my $now = Time::HiRes::time(); eval { local $SIG{ALRM} = sub {die}; Time::HiRes::alarm(0.1); $c->get('foo'); sleep(60); Time::HiRes::alarm(0); }; ok((Time::HiRes::time() - $now) < 1, "should have alarmed my way out of the eval in < 1 second"); unlink $share_file;
I imagine this is somewhat system-dependent behavior. My system: $ uname -a Linux devquery23i 2.6.29.1-ls #1 SMP Tue Apr 14 15:39:46 PDT 2009 x86_64 GNU/Linux Also here's an strace showing the problematic interaction: setitimer(ITIMER_REAL, {it_interval={0, 0}, it_value={0, 100000}}, NULL) = 0 alarm(10) = 1 fcntl(3, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=5308416, len=65536}) = 0 alarm(1) = 10 Looks like alarm() returns a rounded-up integer in the case where there's a high-resolution alarm set... but since setitimer() allows microsecond granularity, this can be off by many orders of magnitude.
I've made the whole setting alarm() thing optional now, you have to explicitly set the catch_deadlocks => 1 argument in 1.36. Assuming you don't set that, it doesn't set any alarm() calls so shouldn't clobber your existing timer.