]>
git.p6c8.net - selfforum.git/blob - selfforum-cgi/shared/Lock.pm
3 ################################################################################
5 # File: shared/Lock.pm #
7 # Authors: Andre Malo <nd@o3media.de>, 2001-04-01 #
9 # Description: file locking #
11 ################################################################################
23 ################################################################################
27 use base
qw(Exporter);
61 ################################################################################
63 # Windows section (no symlinks)
66 ### sub w_lock_file ($;$) ######################################################
68 # set read lock (shared lock)
69 # (for no-symlink-systems)
71 # Params: $filename - file to lock
72 # $timeout - Lock Timeout (sec.)
74 # Return: Status Code (Bool)
76 sub w_lock_file
($;$) {
78 my $timeout = +shift || $Timeout;
80 if (-f
&masterlockfile
($filename)) {
83 # try to increment the reference counter
85 &set_ref
($filename,1,$timeout) and return 1;
92 # or file has not been realeased yet
98 # maybe the system is occupied
102 ### sub w_unlock_file ($;$) ####################################################
104 # remove read lock (shared lock)
105 # (for no-symlink-systems)
107 # Params: $filename - locked file
108 # $timeout - timeout (sec.)
110 # Return: Status Code (Bool)
112 sub w_unlock_file
($;$) {
113 my $filename = shift;
114 my $timeout = shift || $Timeout;
116 if (-f
&masterlockfile
($filename)) {
118 # try do decrement the reference counter
120 &set_ref
($filename,-1,$timeout) and return 1;
124 # maybe the system is occupied
125 # or file has not been released yet
130 ### sub w_write_lock_file ($;$) ################################################
132 # set write lock (exclusive lock)
133 # (for no-symlink-systems)
135 # Params: $filename - file to lock
136 # $timeout - timeout (sec.)
138 # Return: Status Code (Bool)
140 sub w_write_lock_file
($;$) {
142 my $timeout= shift || $Timeout;
144 if (-f
&masterlockfile
($filename) or $iAmMaster) {
146 # announce the write lock
147 # and wait $timeout seconds for
148 # references == 0 (no shared locks set)
150 &simple_lock
($filename,$timeout) or return;
152 # lock reference counter
155 unless (&simple_lock
(&reffile
($filename),$timeout)) {
156 &simple_unlock
($filename,$timeout);
160 # ready if we have no shared locks
162 return 1 if (&get_ref
($filename) == 0);
164 # release reference counter
165 # shared locks get the chance to be removed
167 unless (&simple_unlock
(&reffile
($filename),$timeout)) {
168 &simple_unlock
($filename,$timeout);
175 # remove the announcement
177 &simple_unlock
($filename);}
181 # or file has not been released yet
186 # maybe the system is occupied
191 ### sub w_write_unlock_file ($;$) ##############################################
193 # remove write lock (exclusive lock)
194 # (for no-symlink-systems)
196 # Params: $filename - locked file
197 # $timeout - timeout (sec.)
199 # Return: Status Code (Bool)
201 sub w_write_unlock_file
($;$) {
202 my $filename = shift;
203 my $timeout = shift || $Timeout;
205 if (-f
&masterlockfile
($filename) or $iAmMaster) {
207 # remove reference counter lock
209 &simple_unlock
(&reffile
($filename),$timeout) or return;
211 # remove the write lock announce
213 &simple_unlock
($filename,$timeout) or return;}
219 ### sub w_violent_unlock_file ($) ##############################################
221 # remove any lock violent (excl. master lock)
222 # (for no-symlink-systems)
224 # Params: $filename - locked file
226 # Return: -none- (the success is not defined)
228 sub w_violent_unlock_file
($) {
229 my $filename = shift;
231 if (-f
&masterlockfile
($filename)) {
233 # find out last modification time
234 # and do nothing unless 'violent-timout' is over
237 if (-f
($reffile = $filename) or -f
($reffile = &lockfile
($filename))) {
238 my $time = (stat $reffile)[9];
239 return if ((time - $time) < $violentTimeout);}
241 write_lock_file
($filename,1); # last try, to set an exclusive lock on $filename
242 unlink (&reffile
($filename)); # reference counter = 0
243 simple_unlock
(&reffile
($filename)); # release reference counter file
244 simple_unlock
($filename);} # release file
249 ### sub w_set_master_lock ($;$) ################################################
252 # (for no-symlink-systems)
254 # Params: $filename - file to lock
255 # $timeout - timeout (sec.)
257 # Return: Status Code (Bool)
259 sub w_set_master_lock
($;$) {
260 my $filename = shift;
261 my $timeout = shift || $masterTimeout;
263 # set exclusive lock or fail
265 return unless (&write_lock_file
($filename,$timeout));
269 unlink &masterlockfile
($filename) and return 1;
271 # no chance (occupied?, master lock set yet?)
275 ### sub w_release_file ($) #####################################################
277 # remove any locks (incl. master lock)
278 # (for no-symlink-systems)
280 # Params: $filename - file to lock
281 # $timeout - timeout (sec.)
283 # Return: Status Code (Bool)
285 sub w_release_file
($) {
288 unlink (&reffile
($filename)); # reference counter = 0
289 return if (-f
&reffile
($filename)); # really?
290 return unless (simple_unlock
(&reffile
($filename))); # release reference counter
291 return unless (&simple_unlock
($filename)); # remove any write lock announce
292 return unless (&simple_unlock
(&masterfile
($filename))); # remove master lock
298 ################################################################################
300 # *n*x section (symlinks possible)
303 ### sub x_lock_file ($;$) ######################################################
305 # set read lock (shared lock)
306 # (symlinks possible)
308 # Params: $filename - file to lock
309 # $timeout - Lock Timeout (sec.)
311 # Return: Status Code (Bool)
313 sub x_lock_file
($;$) {
314 my $filename = shift;
315 my $timeout = shift || $Timeout;
317 unless (-l
&masterlockfile
($filename)) {
320 # try to increment the reference counter
322 &set_ref
($filename,1,$timeout) and return 1;
329 # or file has not been realeased yet
335 # maybe the system is occupied
339 ### sub x_unlock_file ($;$) ####################################################
341 # remove read lock (shared lock)
342 # (symlinks possible)
344 # Params: $filename - locked file
345 # $timeout - timeout (sec.)
347 # Return: Status Code (Bool)
349 sub x_unlock_file
($;$) {
351 my ($timeout)=(shift (@_) or $Timeout);
353 unless (-l
&masterlockfile
($filename)) {
354 # try do decrement the reference counter
356 &set_ref
($filename,-1,$timeout) and return 1;}
359 # maybe the system is occupied
360 # or file has not been released yet
365 ### sub x_write_lock_file ($;$) ################################################
367 # set write lock (exclusive lock)
368 # (symlinks possible)
370 # Params: $filename - file to lock
371 # $timeout - timeout (sec.)
373 # Return: Status Code (Bool)
375 sub x_write_lock_file
($;$) {
376 my $filename = shift;
377 my $timeout = shift || $Timeout;
379 unless (-l
&masterlockfile
($filename) and not $iAmMaster) {
380 # announce the write lock
381 # and wait $timeout seconds for
382 # references == 0 (no shared locks set)
384 &simple_lock
($filename,$timeout) or return;
387 # lock reference counter
390 unless (&simple_lock
(&reffile
($filename),$timeout)) {
391 &simple_unlock
($filename,$timeout);
395 # ready if we have no shared locks
397 return 1 if (&get_ref
($filename) == 0);
399 # release reference counter
400 # shared locks get the chance to be removed
402 unless (&simple_unlock
(&reffile
($filename),$timeout)) {
403 &simple_unlock
($filename,$timeout);
410 # remove the announcement
412 &simple_unlock
($filename);}
416 # or file has not been released yet
422 # maybe the system is occupied
427 ### sub x_write_unlock_file ($;$) ##############################################
429 # remove write lock (exclusive lock)
430 # (symlinks possible)
432 # Params: $filename - locked file
433 # $timeout - timeout (sec.)
435 # Return: Status Code (Bool)
437 sub x_write_unlock_file
($;$) {
438 my $filename = shift;
439 my $timeout = shift || $Timeout;
441 unless (-l
&masterlockfile
($filename) and not $iAmMaster) {
442 # remove reference counter lock
444 &simple_unlock
(&reffile
($filename),$timeout) or return;
446 # remove the write lock announce
448 &simple_unlock
($filename,$timeout) or return;
455 ### sub x_violent_unlock_file ($) ##############################################
457 # remove any lock violent (excl. master lock)
458 # (symlinks possible)
460 # Params: $filename - locked file
462 # Return: -none- (the success is not defined)
464 sub x_violent_unlock_file
($) {
467 unless (-l
&masterlockfile
($filename)) {
469 # find out last modification time
470 # and do nothing unless 'violent-timout' is over
474 if (-f
($reffile = $filename)) {
475 $time = (stat $reffile)[9];}
477 elsif (-l
($reffile = &lockfile
($filename))) {
478 $time = (lstat $reffile)[9];}
481 return if ((time - $time) < $violentTimeout);}
483 write_lock_file
($filename,1); # last try, to set an exclusive lock on $filename
484 unlink (&reffile
($filename)); # reference counter = 0
485 simple_unlock
(&reffile
($filename)); # release reference counter file
486 simple_unlock
($filename);} # release file
489 ### sub x_set_master_lock ($;$) ################################################
492 # (symlinks possible)
494 # Params: $filename - file to lock
495 # $timeout - timeout (sec.)
497 # Return: Status Code (Bool)
499 sub x_set_master_lock
($;$) {
500 my $filename = shift;
501 my $timeout = shift || $masterTimeout;
503 # set exclusive lock or fail
505 return unless (&write_lock_file
($filename,$timeout));
509 symlink $filename, &masterlockfile
($filename) and return 1;
511 # no chance (occupied?, master lock set yet?)
515 ### sub x_release_file ($) #####################################################
517 # remove any locks (incl. master lock)
518 # (symlinks possible)
520 # Params: $filename - file to lock
521 # $timeout - timeout (sec.)
523 # Return: Status Code (Bool)
525 sub x_release_file
($) {
528 unlink (&reffile
($filename)); # reference counter = 0
529 return if (-f
&reffile
($filename)); # really?
530 return unless (simple_unlock
(&reffile
($filename))); # release reference counter
531 return unless (&simple_unlock
($filename)); # remove any write lock announce
532 return unless (&simple_unlock
(&masterfile
($filename))); # remove master lock
538 ################################################################################
543 ### sub ~file ($) ##############################################################
545 # create lock file names
553 sub masterlockfile
($) {
554 &lockfile
(&masterfile
($_[0]));
560 ### sub w_simple_lock ($;$) ####################################################
561 ### sub w_simple_unlock ($) ####################################################
563 # simple file lock/unlock
564 # (for no-symlink-systems: kill/create lockfile)
566 # Params: $filename - file to lock
567 # [ $timeout - Lock time out (sec.) ]
569 # Return: Status Code (Bool)
571 sub w_simple_lock
($;$) {
572 my $filename = shift;
573 my $timeout = shift || $Timeout;
574 my $lockfile = lockfile
$filename;
577 unlink $lockfile and return 1;
586 sub w_simple_unlock
($) {
587 my $filename = shift;
588 my $lockfile = lockfile
$filename;
591 if (open(LF
, "> $lockfile")) {
592 return 1 if close (LF
);
595 # not able to create lockfile, hmmm...
600 ### sub w_simple_lock ($;$) ####################################################
601 ### sub w_simple_unlock ($) ####################################################
603 # simple file lock/unlock
604 # (symlinks possible: create/unlink symlink)
606 # Params: $filename - file to lock
607 # [ $timeout - Lock time out (sec.) ]
609 # Return: Status Code (Bool)
611 sub x_simple_lock
($;$) {
612 my $filename = shift;
613 my $timeout = shift || $Timeout;
614 my $lockfile = lockfile
$filename;
617 symlink $filename,$lockfile and return 1;
622 # locking failed (occupied?)
627 sub x_simple_unlock
($) {
630 unlink (&lockfile
($filename)) and return 1;
632 # not able to unlink symlink, hmmm...
637 ### sub w_set_ref ($$$) ########################################################
639 # add $_[1] to reference counter
640 # (may be negative...)
641 # (for no-symlink-systems)
643 # Params: $filename - file, reference counter belongs to
644 # $z - value, added to reference counter
645 # $timeout - lock time out
647 # Return: Status Code (Bool)
649 sub w_set_ref
($$$) {
650 my $filename = shift;
652 my $timeout = shift || $Timeout;
654 my $reffile = reffile
$filename;
657 # if write lock announced, only count down allowed
660 return unless(-f lockfile
($filename));
663 # lock reference counter file
665 return unless(&simple_lock
($reffile,$timeout));
667 # load reference counter
669 unless (open REF
,"<$reffile") {
678 # compute and write new ref. counter
681 $old = 0 if ($old < 0);
683 # kill reference counter file
684 # if ref. counter == 0
687 unlink $reffile or return;
690 open REF
,">$reffile" or return;
691 print REF
$old or return;
695 # release ref. counter file
697 return unless(&simple_unlock
($reffile));
703 ### sub x_set_ref ($$$) ########################################################
705 # add $_[1] to reference counter
706 # (may be negative...)
707 # (symlinks possible)
709 # Params: $filename - file, reference counter belongs to
710 # $z - value, added to reference counter
711 # $timeout - lock time out
713 # Return: Status Code (Bool)
715 sub x_set_ref
($$$) {
716 my $filename = shift;
718 my $timeout = shift || $Timeout;
720 my $reffile = reffile
$filename;
723 # if write lock announced, only count down allowed
726 return if(-l
&lockfile
($filename));
729 # lock reference counter file
731 return unless(&simple_lock
($reffile,$timeout));
733 # load reference counter
735 unless (open REF
,"<$reffile") {
744 # compute and write new ref. counter
747 $old = 0 if ($old < 0);
749 unlink $reffile or return;
752 open REF
,">$reffile" or return;
753 print REF
$old or return;
757 # release ref. counter file
759 return unless(&simple_unlock
($reffile));
765 ### sub get_ref ($) ############################################################
767 # read out the reference counter
768 # (system independant)
771 # Params: $filename - file, the ref. counter belongs to
773 # Return: reference counter
776 my $filename = shift;
777 my $reffile = reffile
$filename;
781 unless (open REF
,"< $reffile") {
794 ################################################################################
796 # initializing the module
799 # global variables (time in seconds)
801 $Timeout = 10; # normal timeout
802 $violentTimeout = 600; # violent timeout (10 minutes)
803 $masterTimeout = 20; # master timeout
805 $iAmMaster = 0; # default: I am nobody
807 # assign the aliases to the needed functions
808 # (perldoc -f symlink)
810 if ( eval {local $SIG{__DIE__
}; symlink('',''); 1 } ) {
811 *lock_file
= \
&x_lock_file
;
812 *unlock_file
= \
&x_unlock_file
;
813 *write_lock_file
= \
&x_write_lock_file
;
814 *write_unlock_file
= \
&x_write_unlock_file
;
815 *violent_unlock_file
= \
&x_violent_unlock_file
;
816 *set_master_lock
= \
&x_set_master_lock
;
817 *release_file
= \
&x_release_file
;
819 *simple_lock
= \
&x_simple_lock
;
820 *simple_unlock
= \
&x_simple_unlock
;
821 *set_ref
= \
&x_set_ref
;
825 *lock_file
= \
&w_lock_file
;
826 *unlock_file
= \
&w_unlock_file
;
827 *write_lock_file
= \
&w_write_lock_file
;
828 *write_unlock_file
= \
&w_write_unlock_file
;
829 *violent_unlock_file
= \
&w_violent_unlock_file
;
830 *set_master_lock
= \
&w_set_master_lock
;
831 *release_file
= \
&w_release_file
;
833 *simple_lock
= \
&w_simple_lock
;
834 *simple_unlock
= \
&w_simple_unlock
;
835 *set_ref
= \
&w_set_ref
;
839 # keeping require happy
844 ### end of Lock ################################################################
patrick-canterino.de