File Coverage

blib/lib/Dir/Flock.pm
Criterion Covered Total %
statement 98 235 41.7
branch 19 114 16.6
condition 8 39 20.5
subroutine 21 32 65.6
pod 12 12 100.0
total 158 432 36.5


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