@@ -194,13 +194,23 @@ sub import {
194194
195195 if ( $state_file -> {file_handle } ) {
196196
197- # TODO probably need to check for failure, but then what do I do?
198- eval {
199- local $SIG {' ALRM' } = sub { die " flock 8 timeout\n " ; };
200- my $orig_alarm = alarm $state_file -> {flock_timeout };
201- flock $state_file -> {file_handle }, 8;
202- alarm $orig_alarm ;
203- };
197+ # Try a non-blocking call first as
198+ # it will avoid two alarm syscalls
199+ # if possible.
200+ # If the nonblocking call does not
201+ # complete right away we fallback to
202+ # the full expensive
203+ # signal handler setup/alarm/flock/alarm call
204+ if ( !flock $state_file -> {file_handle }, 8 | Fcntl::LOCK_NB() ) {
205+
206+ # TODO probably need to check for failure, but then what do I do?
207+ eval {
208+ local $SIG {' ALRM' } = sub { die " flock 8 timeout\n " ; };
209+ my $orig_alarm = alarm $state_file -> {flock_timeout };
210+ flock $state_file -> {file_handle }, 8;
211+ alarm $orig_alarm ;
212+ };
213+ }
204214 close $state_file -> {file_handle };
205215 $state_file -> {file_handle } = undef ;
206216
@@ -241,21 +251,32 @@ sub import {
241251
242252 open my $fh , $mode , $state_file -> {file_name }
243253 or $state_file -> throw(" Unable to open state file '$state_file ->{file_name}': $! " );
244- eval {
245- local $SIG {' ALRM' } = sub { die " flock 2 timeout\n " ; };
246- my $orig_alarm = alarm $state_file -> {flock_timeout };
247- flock $fh , 2;
248- alarm $orig_alarm ;
249- 1;
250- } or do {
251- close ($fh );
252- if ( $@ eq " flock 2 timeout\n " ) {
253- $state_file -> throw(' Guard timed out trying to open state file.' );
254- }
255- else {
256- $state_file -> throw($@ );
257- }
258- };
254+
255+ # Try a non-blocking call first as
256+ # it will avoid two alarm syscalls
257+ # if possible.
258+ # If the nonblocking call does not
259+ # complete right away we fallback to
260+ # the full expensive
261+ # signal handler setup/alarm/flock/alarm call
262+ if ( !flock $fh , 2 | Fcntl::LOCK_NB() ) {
263+
264+ eval {
265+ local $SIG {' ALRM' } = sub { die " flock 2 timeout\n " ; };
266+ my $orig_alarm = alarm $state_file -> {flock_timeout };
267+ flock $fh , 2;
268+ alarm $orig_alarm ;
269+ 1;
270+ } or do {
271+ close ($fh );
272+ if ( $@ eq " flock 2 timeout\n " ) {
273+ $state_file -> throw(' Guard timed out trying to open state file.' );
274+ }
275+ else {
276+ $state_file -> throw($@ );
277+ }
278+ };
279+ }
259280 $state_file -> {file_handle } = $fh ;
260281 }
261282
0 commit comments