File Coverage

blib/lib/Dir/Flock.pm
Criterion Covered Total %
statement 153 233 65.6
branch 44 112 39.2
condition 16 39 41.0
subroutine 25 32 78.1
pod 12 12 100.0
total 250 428 58.4


line stmt bran cond sub pod time code
1             package Dir::Flock;
2 14     14   930082 use strict;
  14         141  
  14         413  
3 14     14   80 use warnings;
  14         21  
  14         384  
4 14     14   91 use Carp;
  14         47  
  14         906  
5 14     14   8172 use Time::HiRes;
  14         20935  
  14         52  
6 14     14   12947 use File::Temp;
  14         313046  
  14         1009  
7 14     14   112 use Fcntl ':flock';
  14         31  
  14         1692  
8 14     14   9379 use Data::Dumper; # when debugging is on
  14         99422  
  14         907  
9 14     14   104 use base 'Exporter';
  14         37  
  14         42796  
10              
11             our $VERSION = '0.07';
12             my %TMPFILE;
13             my %LOCK;
14             our @EXPORT_OK = qw(getDir lock lock_ex lock_sh unlock lockobj lockobj_ex
15             lockobj_sh sync sync_ex sync_sh);
16             our %EXPORT_TAGS = ('all' => \@EXPORT_OK);
17             our $errstr;
18              
19             # configuration that may be updated by user
20             our $LOCKFILE_STUB = "dir-flock-";
21             our $PAUSE_LENGTH = 0.001; # seconds
22             our $HEARTBEAT_CHECK = 30; # seconds
23             our $_DEBUG = $ENV{DEBUG} || $ENV{DIR_FLOCK_DEBUG} || 0;
24              
25             sub getDir {
26 10     10 1 20005120 my $rootdir = shift;
27 10 50 33     746 if (-f $rootdir && ! -d $rootdir) {
28 0         0 require Cwd;
29 0         0 require File::Basename;
30 0         0 $rootdir = File::Basename::dirname(Cwd::abs_path($rootdir));
31             }
32 10         250 my $tmpdir = File::Temp::tempdir(
33             TEMPLATE => "dflock-XXXXXX",
34             DIR => $rootdir, CLEANUP => 1 );
35 10         10330 $tmpdir;
36             }
37              
38             ### core functions
39              
40 8     8 1 346088 sub lock { goto &lock_ex }
41              
42             sub lock_ex {
43 15     15 1 5153 my ($dir, $timeout) = @_;
44 15         259 $errstr = "";
45 15 50       274 return if !_validate_dir($dir);
46 15   33     177 my $P = $_DEBUG && _pid();
47 15         195 my ($filename,$now) = _create_tempfile( $dir, "excl" );
48 15         67 my $last_check = $now;
49 15   100     429 my $expire = $now + ($timeout || 0);
50 15         89 $TMPFILE{ $filename } = _pid();
51 15         114 while (_oldest_file($dir) ne $filename) {
52 117         27951 unlink $filename;
53 117         997 delete $TMPFILE{$filename};
54 117 50       645 $P && print STDERR "$P $filename not the oldest file...\n";
55 117 100 100     893 if (defined($timeout) && Time::HiRes::time > $expire) {
56 5         79 $errstr = "timeout waiting for exclusive lock for '$dir'";
57 5 50       32 $P && print STDERR "$P timeout waiting for lock\n";
58 5         27 return;
59             }
60 112         33742047 Time::HiRes::sleep 0.3 + 2 * rand() * $PAUSE_LENGTH;
61 112 100       4527 if (Time::HiRes::time > $last_check + $HEARTBEAT_CHECK) {
62 1 50       13 $P && print STDERR "$P check heartbeat of lock holder\n";
63 1         23 _ping_oldest_file($dir);
64 1         7 $last_check = Time::HiRes::time;
65             }
66 112         1050 ($filename,$now) = _create_tempfile( $dir, "excl" );
67 112         718 $TMPFILE{ $filename } = _pid();
68             }
69 10 50       70 $P && print STDERR "$P lock successful to $filename\n";
70 10         115 $LOCK{$dir}{_pid()} = $filename;
71 10         102 1;
72             }
73              
74             sub lock_sh {
75 4     4 1 19897 my ($dir, $timeout) = @_;
76 4         56 $errstr = "";
77 4 50       105 return if !_validate_dir($dir);
78 4   33     39 my $P = $_DEBUG && _pid();
79 4         54 my ($filename,$now) = _create_tempfile( $dir, "shared" );
80 4         24 my $last_check = $now;
81 4   50     60 my $expire = $now + ($timeout || 0);
82 4         14 $TMPFILE{ $filename } = _pid();
83 4         43 while (_oldest_file($dir) =~ /_excl_/) {
84 35         4320 unlink $filename;
85 35         363 delete $TMPFILE{$filename};
86 35 50       207 $P && print STDERR "$P $filename not the oldest file...\n";
87 35 100 66     234 if (defined($timeout) && Time::HiRes::time > $expire) {
88 1         5 $errstr = "timeout waiting for exclusive lock for '$dir'";
89 1 50       2 $P && print STDERR "$P timeout waiting for lock\n";
90 1         5 return;
91             }
92 34         10245194 Time::HiRes::sleep 0.3 + 2 * rand() * $PAUSE_LENGTH;
93 34 50       1495 if (Time::HiRes::time > $last_check + $HEARTBEAT_CHECK) {
94 0 0       0 $P && print STDERR "$P check heartbeat of lock holder\n";
95 0         0 _ping_oldest_file($dir);
96 0         0 $last_check = Time::HiRes::time;
97             }
98 34         386 ($filename,$now) = _create_tempfile( $dir, "shared" );
99 34         246 $TMPFILE{ $filename } = _pid();
100             }
101 3 50       15 $P && print STDERR "$P lock successful to $filename\n";
102 3         29 $LOCK{$dir}{_pid()} = $filename;
103 3         19 1;
104             }
105              
106             ### flock semantics
107              
108             sub flock {
109 5     5 1 10019756 my ($dir, $op) = @_;
110 5         53 my $timeout = undef;
111 5 100       105 if ($op & LOCK_NB) {
112 1         17 $timeout = 0;
113             }
114 5 100       70 if ($op & LOCK_EX) {
115 3         89 return lock_ex($dir,$timeout);
116             }
117 2 50       34 if ($op & LOCK_SH) {
118 0         0 return lock_sh($dir,$timeout);
119             }
120 2 50       18 if ($op & LOCK_UN) {
121 2         13 return unlock($dir);
122             }
123 0         0 $errstr = "invalid flock operation '$op'";
124 0         0 carp "Dir::Flock::flock: invalid operation";
125 0         0 return;
126             }
127              
128             sub unlock {
129 14     14 1 30015846 my ($dir) = @_;
130 14 100       120 if (!defined $LOCK{$dir}) {
131 1 50       179 return if __inGD();
132 1         5 $errstr = "lock for '$dir' not held by " . _pid()
133             . " nor any proc";
134 1         573 carp "Dir::Flock::unlock: $errstr";
135 1         8 return;
136             }
137 13         96 my $filename = delete $LOCK{$dir}{_pid()};
138 13 50       75 if (!defined($filename)) {
139 0 0       0 return if __inGD();
140 0         0 $errstr = "lock for '$dir' not held by " . _pid();
141 0         0 carp "Dir::Flock::unlock: $errstr";
142 0         0 return;
143             }
144 13 50       111 $_DEBUG && print STDERR _pid()," unlocking $filename\n";
145 13 50       389 if (! -f $filename) {
146 0 0       0 return if __inGD();
147 0         0 $errstr = "lock file '$filename' is missing";
148             carp "Dir::Flock::unlock: lock file is missing ",
149 0         0 %{$LOCK{$dir}};
  0         0  
150 0         0 return;
151             }
152 13         958 my $z = unlink($filename);
153 13 50       149 if ($z) {
154 13 50       63 $_DEBUG && print STDERR _pid()," deleted $filename\n";
155 13 50       99 $_DEBUG && print STDERR "$dir contains:\n",join(" ",glob("$dir/*")),"\n";
156 13         84 delete $TMPFILE{$filename};
157 13         101 return $z;
158             }
159 0 0       0 return if __inGD();
160 0         0 $errstr = "unlink called failed on file '$filename'";
161 0         0 carp "Dir::Flock::unlock: failed to unlink lock file ",
162             "'$filename'";
163 0         0 return; # this could be bad
164             }
165              
166             ### scope semantics
167              
168 0     0 1 0 sub lockobj { goto &lockobj_ex }
169              
170             sub lockobj_ex {
171 0     0 1 0 my ($dir, $timeout) = @_;
172 0         0 my $ok = lock_ex($dir,$timeout);
173 0 0       0 return if !$ok;
174 0         0 return bless \$dir, 'Dir::Flock::SyncObject2';
175             }
176              
177             sub lockobj_sh {
178 0     0 1 0 my ($dir, $timeout) = @_;
179 0         0 my $ok = lock_sh($dir,$timeout);
180 0 0       0 return if !$ok;
181 0         0 return bless \$dir, 'Dir::Flock::SyncObject2';
182             }
183              
184             sub Dir::Flock::SyncObject2::DESTROY {
185 0     0   0 my $self = shift;
186 0         0 my $dir = $$self;
187 0         0 my $ok = unlock($dir);
188 0 0 0     0 if (!$ok && !__inGD()) {
189             # $errstr set in unlock
190 0         0 carp "unlock: failed for dir '$dir' as sync object went out of scope";
191             }
192 0         0 return;
193             }
194              
195             ### block semantics
196              
197 0     0 1 0 sub sync (&$;$) { goto &sync_ex }
198              
199             sub sync_ex (&$;$) {
200 0     0 1 0 my ($code, $dir, $timeout) = @_;
201 0 0       0 if (!lock_ex($dir,$timeout)) {
202             # $errstr set in lock_ex
203 0         0 return;
204             }
205 0         0 my @r;
206 0 0       0 if (wantarray) {
207 0         0 @r = eval { $code->() };
  0         0  
208             } else {
209 0         0 $r[0] = eval { $code->() };
  0         0  
210             }
211 0         0 unlock($dir);
212 0 0       0 if ($@) {
213 0         0 $errstr = "error from sync_ex BLOCK: $@";
214 0         0 die $@;
215             }
216 0 0       0 wantarray ? @r : $r[0];
217             }
218              
219             sub sync_sh (&$;$) {
220 0     0 1 0 my ($code, $dir, $timeout) = @_;
221 0 0       0 if (!lock_sh($dir,$timeout)) {
222             # $errstr set in lock_sh
223 0         0 return;
224             }
225 0         0 my @r;
226 0 0       0 if (wantarray) {
227 0         0 @r = eval { $code->() };
  0         0  
228             } else {
229 0         0 $r[0] = eval { $code->() };
  0         0  
230             }
231 0         0 unlock($dir);
232 0 0       0 if ($@){
233 0         0 $errstr = "error from sync_sh BLOCK: $@";
234 0         0 die $@;
235             }
236 0 0       0 wantarray ? @r : $r[0];
237             }
238              
239             ### utilities
240              
241             sub _host {
242             $ENV{HOSTNAME} || ($^O eq 'MSWin32' && $ENV{COMPUTERNAME})
243 372 0 0 372   3311 || "localhost";
      33        
244             }
245              
246             sub _pid {
247 371     371   1592 my $host = _host();
248 371 50       11163 join("_", $host, $$, $INC{"threads.pm"} ? threads->tid : ());
249             }
250              
251             sub _create_tempfile {
252 165     165   2129 my ($dir,$type) = @_;
253 165   50     1022 $type ||= "excl";
254 165         1042 my $now = Time::HiRes::time;
255 165         1720 my $file = sprintf "$dir/%s_%s_%s_%s", $LOCKFILE_STUB,
256             $now, $type, _pid();
257 165         36227 open my $fh, ">>", $file;
258 165         6321 return ($file,$now);
259             }
260              
261             sub _oldest_file {
262 166     166   853 my ($dir, $excl) = @_;
263 166         434 my $dh;
264 166         979 _refresh_dir($dir); # is this necessary? is this sufficient?
265 166         22542 my @f1 = sort glob("$dir/$LOCKFILE_STUB*");
266 166 50       1422 if ($excl) {
267 0         0 @f1 = grep /_excl_/, @f1;
268             }
269 166 50       2869 @f1 > 0 && $f1[0];
270             }
271              
272             sub _ping_oldest_file {
273 1     1   11 my ($dir,$excl) = @_;
274 1         8 my $file = _oldest_file($dir,$excl);
275 1 50       10 return unless $file;
276 1         2 my $file0 = $file;
277 1         67 $file0 =~ s/.*$LOCKFILE_STUB.//;
278 1         10 my ($time, $type, $host, $pid, $tid) = split /_/, $file0;
279 1         23 $pid =~ s/\D+$//;
280 1 50       13 $_DEBUG && print STDERR _pid(), ": ping host=$host pid=$pid tid=$tid\n";
281 1 50       4 $_DEBUG && print STDERR "$dir holds:\n", join(" ",glob("$dir/*")),"\n";
282 1         3 my $status;
283              
284              
285             # TODO: what if $tid is defined? How do you signal a thread
286             # and how do you signal or terminate a remote thread?
287            
288 1 50 33     19 if ($host eq _host() || $host eq 'localhost') {
289             # TODO: more robust way to inspect process on local machine.
290             # kill 'ZERO',... can mislead for a number of reasons, such as
291             # if the process is owned by a different user.
292 1         24 $status = kill 'ZERO', $pid;
293 1 50       6 $_DEBUG && print STDERR _pid(), " local kill ZERO => $pid: $status\n";
294             } else {
295             # TODO: need a more robust way to inspect a process on a remote machine
296 0         0 my $c1 = system("ssh $host kill -0 $pid");
297 0         0 $status = ($c1 == 0);
298 0 0       0 $_DEBUG && print STDERR _pid(),
299             " remote kill ZERO => $host:$pid: $status\n";
300             }
301 1 50       6 if (! $status) {
302 1         61 warn "Dir::Flock: lock holder that created $file appears dead\n";
303 1         90 unlink $file;
304             }
305             }
306              
307             sub _refresh_dir {
308             # https://stackoverflow.com/a/30630912
309             # "Within a given process, calling opendir and closedir on the
310             # parent directory of a file invalidates the NFS cache."
311 185     185   827 my $dir = shift;
312 185         494 my $dh;
313 185         10273 opendir $dh, $dir;
314 185         4040 closedir $dh;
315 185         1797 return;
316             }
317              
318             sub _validate_dir {
319 19     19   168 my $dir = shift;
320 19 50       898 if (! -d $dir) {
321 0         0 $errstr = "lock dir '$dir' is not a directory";
322 0         0 carp "Dir::Flock::lock: $errstr";
323 0         0 return;
324             }
325 19 0 33     676 if (! -r $dir && -w $dir && -x $dir) {
      33        
326 0         0 $errstr = "lock dir '$dir' is not an accessible directory";
327 0         0 carp "Dir::Flock::lock: $errstr";
328 0         0 return;
329             }
330 19         214 _refresh_dir($dir);
331 19         133 1;
332             }
333              
334             BEGIN {
335 14 50   14   128 if (defined(${^GLOBAL_PHASE})) {
336 14 50       1448 eval 'sub __inGD(){%{^GLOBAL_PHASE} eq q{DESTRUCT} && __END()};1'
337             } else {
338 0         0 require B;
339 0         0 eval 'sub __inGD(){${B::main_cv()}==0 && __END()};1'
340             }
341             }
342              
343             END {
344 14     13   23253 my $p = _pid();
345 14     14   103 no warnings 'redefine';
  14         29  
  14         3426  
346 13     1   442 *DB::DB = sub {};
347 13         350 *__inGD = sub () { 1 };
348 13         344 unlink grep{ $TMPFILE{$_} eq $p } keys %TMPFILE;
  0            
349             }
350              
351             1;
352              
353             =head1 NAME
354              
355             Dir::Flock - advisory locking of a dedicated directory
356              
357              
358              
359             =head1 VERSION
360              
361             0.07
362              
363              
364              
365             =head1 SYNOPSIS
366              
367             use Dir::Flock;
368             my $dir = Dir::Flock::getDir("/home/mob/projects/foo");
369             my $success = Dir::Flock::lock($dir);
370             # ... synchronized code
371             $success = Dir::Flock::unlock($dir);
372              
373             # flock semantics
374             use Fcntl ':flock';
375             $success = Dir::Flock::flock($dir, LOCK_EX | LOCK_NB);
376             ...
377             Dir::Flock::flock($dir, LOCK_UN);
378              
379             # mutex/scoping semantics
380             {
381             my $lock = Dir::Flock::lockobj($dir);
382             ... synchronized code ...
383             } # lock released when $lock goes out of scope
384              
385             # code ref semantics
386             Dir::Flock::sync {
387             ... synchronized code ...
388             }, $dir
389              
390              
391              
392             =head1 DESCRIPTION
393              
394             C implements advisory locking of a directory.
395             The use case is to execute synchronized code (code that should
396             only be executed by one process or thread at a time) or provide
397             exclusive access to a file or other resource. C has
398             more overhead than some of the other synchronization techniques
399             available to Perl programmers, but it might be the only technique
400             that works on NFS (Networked File System).
401              
402             =head2 Algorithm
403              
404             File locking is difficult on NFS because, as I understand it, each
405             node maintains a cache that includes file contents and file metadata.
406             When a system call wants to check whether a lock exists on a file,
407             the filesystem driver might inspect the cached file rather than
408             the file on the server, and it might miss an action taken by another
409             node to lock a file.
410              
411             The cache is not used, again, as I understand it, when the filesystem
412             driver reads a directory. If advisory locking is accomplished through
413             reading the contents of a directory, it will not be affected by NFS's
414             caching behavior.
415              
416             To acquire a lock in a directory, this module writes a small file
417             into the directory. Then it checks if this new file is the "oldest"
418             file in the directory. If it is the oldest file, then the process
419             has acquired the lock. If there is already an older file in the
420             directory, than that file specifies what process has a lock on the
421             directory, and we have to wait and try again later. To unlock the
422             directory, the module simply deletes the file in the directory
423             that represents its lock.
424              
425             =head2 Semantics
426              
427             This module offers several different semantics for advisory
428             locking of a directory.
429              
430             =head3 functional semantics
431              
432             The core L and
433             L functions begin and end advisory
434             locking on a directory. All of the other semantics are implemented in
435             terms of these functions.
436              
437             $ok = Dir::Flock::lock( "/some/path" );
438             $ok = Dir::Flock::lock( "/some/path", $timeout );
439             $ok = Dir::Flock::unlock( "/some/path" );
440              
441             =head3 flock semantics
442              
443             The function L emulates the Perl
444             L builtin, accepting the same arguments
445             for the operation argument.
446              
447             use Fcntl ':flock';
448             $ok = Dir::Flock::flock( "/some/path", LOCK_EX );
449             ...
450             $ok = Dir::Flock::flock( "/some/path", LOCK_UN );
451              
452             =head3 scope-oriented semantics
453              
454             The L function returns an
455             object representing a directory lock. The lock is released
456             when the object goes out of scope.
457              
458             {
459             my $lock = Dir::Flock::lockobj( "/some/path" );
460             ...
461             } # $lock out of scope, lock released
462              
463             =head3 BLOCK semantics
464              
465             The L accepts a block of code or other
466             code reference, to be executed with an advisory lock on a
467             directory.
468              
469             Dir::Flock::sync {
470             ... synchronized code ...
471             } "/some/path";
472              
473              
474             =head1 FUNCTIONS
475              
476             Most functions return a false value and set the package variable
477             C<$Dir::Flock::errstr> if they are unsuccessful.
478              
479              
480             =head2 lock
481              
482             =head2 lock_ex
483              
484             =head2 $success = Dir::Flock::lock( $directory [, $timeout ] )
485              
486             =head2 $success = Dir::Flock::lock_ex( $directory [, $timeout ] )
487              
488             Attempts to obtain an I lock on the given directory. While
489             the directory is locked, the C or C call on the
490             same directory from
491             other processes or threads will block until the directory is unlocked
492             (see L<"unlock">). Returns true if the lock was successfully acquired.
493              
494             If an optional C<$timeout> argument is provided, the function will
495             try for at least C<$timeout> seconds to acquire the lock, and return
496             a false value if it is not successful in that time. Use a timeout of
497             zero to make a "non-blocking" exclusive lock request.
498              
499              
500             =head2 lock_sh
501              
502             =head2 $success = Dir::Flock::lock_sh( $directory [, $timeout ] )
503              
504             Attempts to obtain a I lock on the given directory.
505             While there are shared locks on a directory, other calls to C
506             may also receive a shared lock on the directory but calls to
507             C/C on the directory will block until all
508             shared locks are removed.
509              
510             If an optional C<$timeout> argument is provided, the function will
511             try for at least C<$timeout> seconds to acquire the lock, and
512             return a false value if it is not successful in that time.
513             Use a timeout of zero to make a "non-blocking" shared lock request.
514              
515              
516             =head2 unlock
517              
518             =head2 $success = Dir::Flock::unlock( $directory )
519              
520             Releases the exclusive or shared lock on the given directory held
521             by this process. Returns a false value if the current process did
522             not possess the lock on the directory.
523              
524              
525             =head2 getDir
526              
527             =head2 $tmp_directory = Dir::Flock::getDir( $root )
528              
529             Creates a temporary and empty directory in a subdirectory of C<$root>
530             that is suitable for use as a synchronization directory. The directory
531             will automatically be cleaned up when the process that called this
532             function exits.
533              
534             If the input to C is a filename rather than a directory name,
535             a new subdirectory will be created in the directory where the file
536             is located.
537              
538              
539             =head2 flock
540              
541             =head2 $success = Dir::Flock::flock( $dir, $op )
542              
543             Acquires and releases advisory locks on the given directory
544             with the same semantics as the Perl builtin
545             L function.
546              
547              
548              
549             =head2 lockobj
550              
551             =head2 lockobj_ex
552              
553             =head2 $lock = Dir::Flock::lockobj( $dir [, $timeout] );
554              
555             =head2 $lock = Dir::Flock::lockobj_ex( $dir [, $timeout] );
556              
557             Attempts to acquire an exclusive advisory lock for the given
558             directory. On success, returns a handle to the directory lock
559             with the feature that the lock will be released when the handle
560             goes out of scope. This allows you to use this module with
561             syntax such as
562              
563             {
564             my $lock = Dir::Flock::lockobj( "/some/path" );
565             ... synchronized code ...
566             }
567             # $lock out of scope, so directory lock released
568             ... unsynchronized code ...
569              
570             Optional C<$timeout> argument causes the function to block
571             for a maximum of C<$timeout> seconds attempting to acquire
572             the lock. If C<$timeout> is not provided or is C,
573             the function will block indefinitely while waiting for the
574             lock.
575              
576             Returns a false value and may sets C<$Dir::Flock::errstr> if the function
577             times out or is otherwise unable to acquire the directory lock.
578              
579             C is an alias for C.
580              
581              
582             =head2 lockobj_sh
583              
584             =head2 my $lock = Dir::Flock::lockobj_sh($dir [, $timeout])
585              
586             Analogue to L<"lockobj_ex">. Returns a reference to a shared lock
587             on a directory that will be released when the reference goes
588             out of scope.
589              
590             Returns a false value and may set C<$Dir::Flock::errstr> if the
591             function times out or otherwise fails to acquire a shared lock
592             on the directory.
593              
594              
595             =head2 sync
596              
597             =head2 sync_ex
598              
599             =head2 $result = Dir::Flock::sync CODE $dir [, $timeout]
600              
601             =head2 @result = Dir::Flock::sync_ex CODE $dir [, $timeout]
602              
603             Semantics for executing a block of code while there is an
604             advisory exclusive lock on the given directory. The code can
605             be evaluated in both scalar or list contexts. An optional
606             C<$timeout> argument will cause the function to give up and
607             return a false value if the lock cannot be acquired after
608             C<$timeout> seconds. Callers should be careful to distinguish
609             cases where the specified code reference returns nothing and
610             where the C function times out and returns nothing.
611             One way to distinguish these cases is to check the value of
612             C<$Dir::Flock::errstr>, which will generally be set if there
613             was an issue with the locking mechanics.
614              
615             The lock is released in the event that the given C<$code>
616             produces a fatal error.
617              
618              
619             =head2 sync_sh
620              
621             =head2 $result = Dir::Flock::sync_sh BLOCK $dir [, $timeout]
622              
623             =head2 @result = Dir::Flock::sync_sh BLOCK $dir [, $timeout]
624              
625             Analogue of L<"sync_ex"> but executes the code block while
626             there is an advisory shared lock on the given directory.
627              
628              
629             =head1 DEPENDENCIES
630              
631             C requires L where the C
632             function has subsection resolution.
633              
634              
635             =head1 EXPORTS
636              
637             Nothing is exported from C by default, but all of
638             the functions documented here may be exported by name.
639              
640             Many of the core functions of C have the same name
641             as Perl builtin functions or functions from other popular modules,
642             so users should be wary of importing functions from this module
643             into their working namespace.
644              
645              
646              
647             =head1 VARIABLES
648              
649             =head2 PAUSE_LENGTH
650              
651             =head2 $Dir::Flock::PAUSE_LENGTH
652              
653             C<$Dir::Flock::PAUSE_LENGTH> is the average number of seconds that
654             the module will wait after a failed attempt to acquire a lock before
655             attempting to acquire it again. The default value is 0.001,
656             which is a good setting for having a high throughput when the
657             synchronized operations take a short amount of time. In contexts
658             where the synchronized operations take a longer time, it may
659             be appropriate to increase this value to reduce busy-waiting CPU
660             utilization.
661              
662             =cut
663              
664             # also under VARIABLES: HEARTBEAT_CHECK
665              
666             # =head1 ENVIRONMENT => DIR_FLOCK_DEBUG
667              
668             # =cut
669            
670              
671              
672             =head1 LIMITATIONS
673              
674             See L<"System requirements"> above.
675              
676             The L module can be loaded when necessary
677             to provide a consistent synchronization API on systems that
678             require C to work properly and on systems that
679             don't support C.
680              
681             =cut
682              
683             # =head1 SEE ALSO L, L.
684             # L, L
685              
686              
687             =head1 SUPPORT
688              
689             You can find documentation for this module with the perldoc command.
690              
691             perldoc Dir::Flock
692              
693              
694             You can also look for information at:
695              
696             =over 4
697              
698             =item * CPAN Ratings
699              
700             L
701              
702             =item * Emob@cpan.orgE
703              
704             With the decommissioning of http://rt.cpan.org/,
705             please send bug reports and feature requests
706             directly to the author's email address.
707              
708             =back
709              
710              
711              
712              
713             =head1 AUTHOR
714              
715             Marty O'Brien, Emob@cpan.orgE
716              
717              
718              
719              
720             =head1 LICENSE AND COPYRIGHT
721              
722             Copyright (c) 2019-2020, Marty O'Brien
723              
724             This library is free software; you can redistribute it and/or modify
725             it under the same terms as Perl itself, either Perl version 5.8.8 or,
726             at your option, any later version of Perl 5 you may have available.
727              
728             See http://dev.perl.org/licenses/ for more information.
729              
730             =cut
731              
732              
733              
734             =begin TODO
735              
736             Heartbeat
737              
738             a running process should be able to update the timestamp of
739             their lockfiles (either the mtime known to the filesystem or
740             in the file data themselves) to let other processes (on the
741             same and other hosts) know that the locking process is still
742             alive. Can you do that without releasing the lock?
743              
744             Include heartbeat data in the file names?
745              
746             Threads
747              
748             In _ping_oldest_file , how to detect whether a thread is
749             still alive? How to detect whether a thread on a remote
750             machine is still alive?
751              
752             =end TODO