]>
git.p6c8.net - selfforum.git/blob - selfforum-cgi/shared/Lock.pm
f878aea9856b49cb0ad8349e0e05e133cb918095
3 ################################################################################
5 # File: shared/Lock.pm #
7 # Authors: Andre Malo <nd@o3media.de>, 2001-04-01 #
9 # Description: file locking #
11 ################################################################################
25 ################################################################################
29 use base
qw(Exporter);
63 ################################################################################
65 # Windows section (no symlinks)
68 ### sub w_lock_file ($;$) ######################################################
70 # set read lock (shared lock)
71 # (for no-symlink-systems)
73 # Params: $filename - file to lock
74 # $timeout - Lock Timeout (sec.)
76 # Return: Status Code (Bool)
78 sub w_lock_file
($;$) {
80 my $timeout = +shift || $Timeout;
82 if (-f
&masterlockfile
($filename)) {
85 # try to increment the reference counter
87 &set_ref
($filename,1,$timeout) and return 1;
94 # or file has not been realeased yet
100 # maybe the system is occupied
104 ### sub w_unlock_file ($;$) ####################################################
106 # remove read lock (shared lock)
107 # (for no-symlink-systems)
109 # Params: $filename - locked file
110 # $timeout - timeout (sec.)
112 # Return: Status Code (Bool)
114 sub w_unlock_file
($;$) {
115 my $filename = shift;
116 my $timeout = shift || $Timeout;
118 if (-f
&masterlockfile
($filename)) {
120 # try do decrement the reference counter
122 &set_ref
($filename,-1,$timeout) and return 1;
126 # maybe the system is occupied
127 # or file has not been released yet
132 ### sub w_write_lock_file ($;$) ################################################
134 # set write lock (exclusive lock)
135 # (for no-symlink-systems)
137 # Params: $filename - file to lock
138 # $timeout - timeout (sec.)
140 # Return: Status Code (Bool)
142 sub w_write_lock_file
($;$) {
144 my $timeout= shift || $Timeout;
146 if (-f
&masterlockfile
($filename) or $iAmMaster) {
148 # announce the write lock
149 # and wait $timeout seconds for
150 # references == 0 (no shared locks set)
152 &simple_lock
($filename,$timeout) or return;
154 # lock reference counter
157 unless (&simple_lock
(&reffile
($filename),$timeout)) {
158 &simple_unlock
($filename,$timeout);
162 # ready if we have no shared locks
164 return 1 if (&get_ref
($filename) == 0);
166 # release reference counter
167 # shared locks get the chance to be removed
169 unless (&simple_unlock
(&reffile
($filename),$timeout)) {
170 &simple_unlock
($filename,$timeout);
177 # remove the announcement
179 &simple_unlock
($filename);}
183 # or file has not been released yet
188 # maybe the system is occupied
193 ### sub w_write_unlock_file ($;$) ##############################################
195 # remove write lock (exclusive lock)
196 # (for no-symlink-systems)
198 # Params: $filename - locked file
199 # $timeout - timeout (sec.)
201 # Return: Status Code (Bool)
203 sub w_write_unlock_file
($;$) {
204 my $filename = shift;
205 my $timeout = shift || $Timeout;
207 if (-f
&masterlockfile
($filename) or $iAmMaster) {
209 # remove reference counter lock
211 &simple_unlock
(&reffile
($filename),$timeout) or return;
213 # remove the write lock announce
215 &simple_unlock
($filename,$timeout) or return;}
221 ### sub w_violent_unlock_file ($) ##############################################
223 # remove any lock violent (excl. master lock)
224 # (for no-symlink-systems)
226 # Params: $filename - locked file
228 # Return: -none- (the success is not defined)
230 sub w_violent_unlock_file
($) {
231 my $filename = shift;
233 if (-f
&masterlockfile
($filename)) {
235 # find out last modification time
236 # and do nothing unless 'violent-timout' is over
239 if (-f
($reffile = $filename) or -f
($reffile = &lockfile
($filename))) {
240 my $time = (stat $reffile)[9];
241 return if ((time - $time) < $violentTimeout);}
243 write_lock_file
($filename,1); # last try, to set an exclusive lock on $filename
244 unlink (&reffile
($filename)); # reference counter = 0
245 simple_unlock
(&reffile
($filename)); # release reference counter file
246 simple_unlock
($filename);} # release file
251 ### sub w_set_master_lock ($;$) ################################################
254 # (for no-symlink-systems)
256 # Params: $filename - file to lock
257 # $timeout - timeout (sec.)
259 # Return: Status Code (Bool)
261 sub w_set_master_lock
($;$) {
262 my $filename = shift;
263 my $timeout = shift || $masterTimeout;
265 # set exclusive lock or fail
267 return unless (&write_lock_file
($filename,$timeout));
271 unlink &masterlockfile
($filename) and return 1;
273 # no chance (occupied?, master lock set yet?)
277 ### sub w_release_file ($) #####################################################
279 # remove any locks (incl. master lock)
280 # (for no-symlink-systems)
282 # Params: $filename - file to lock
283 # $timeout - timeout (sec.)
285 # Return: Status Code (Bool)
287 sub w_release_file
($) {
290 unlink (&reffile
($filename)); # reference counter = 0
291 return if (-f
&reffile
($filename)); # really?
292 return unless (simple_unlock
(&reffile
($filename))); # release reference counter
293 return unless (&simple_unlock
($filename)); # remove any write lock announce
294 return unless (&simple_unlock
(&masterfile
($filename))); # remove master lock
300 ################################################################################
302 # *n*x section (symlinks possible)
305 ### sub x_lock_file ($;$) ######################################################
307 # set read lock (shared lock)
308 # (symlinks possible)
310 # Params: $filename - file to lock
311 # $timeout - Lock Timeout (sec.)
313 # Return: Status Code (Bool)
315 sub x_lock_file
($;$) {
316 my $filename = shift;
317 my $timeout = shift || $Timeout;
319 unless (-l
&masterlockfile
($filename)) {
322 # try to increment the reference counter
324 &set_ref
($filename,1,$timeout) and return 1;
331 # or file has not been realeased yet
337 # maybe the system is occupied
341 ### sub x_unlock_file ($;$) ####################################################
343 # remove read lock (shared lock)
344 # (symlinks possible)
346 # Params: $filename - locked file
347 # $timeout - timeout (sec.)
349 # Return: Status Code (Bool)
351 sub x_unlock_file
($;$) {
353 my ($timeout)=(shift (@_) or $Timeout);
355 unless (-l
&masterlockfile
($filename)) {
356 # try do decrement the reference counter
358 &set_ref
($filename,-1,$timeout) and return 1;}
361 # maybe the system is occupied
362 # or file has not been released yet
367 ### sub x_write_lock_file ($;$) ################################################
369 # set write lock (exclusive lock)
370 # (symlinks possible)
372 # Params: $filename - file to lock
373 # $timeout - timeout (sec.)
375 # Return: Status Code (Bool)
377 sub x_write_lock_file
($;$) {
378 my $filename = shift;
379 my $timeout = shift || $Timeout;
381 unless (-l
&masterlockfile
($filename) and not $iAmMaster) {
382 # announce the write lock
383 # and wait $timeout seconds for
384 # references == 0 (no shared locks set)
386 &simple_lock
($filename,$timeout) or return;
389 # lock reference counter
392 unless (&simple_lock
(&reffile
($filename),$timeout)) {
393 &simple_unlock
($filename,$timeout);
397 # ready if we have no shared locks
399 return 1 if (&get_ref
($filename) == 0);
401 # release reference counter
402 # shared locks get the chance to be removed
404 unless (&simple_unlock
(&reffile
($filename),$timeout)) {
405 &simple_unlock
($filename,$timeout);
412 # remove the announcement
414 &simple_unlock
($filename);}
418 # or file has not been released yet
424 # maybe the system is occupied
429 ### sub x_write_unlock_file ($;$) ##############################################
431 # remove write lock (exclusive lock)
432 # (symlinks possible)
434 # Params: $filename - locked file
435 # $timeout - timeout (sec.)
437 # Return: Status Code (Bool)
439 sub x_write_unlock_file
($;$) {
440 my $filename = shift;
441 my $timeout = shift || $Timeout;
443 unless (-l
&masterlockfile
($filename) and not $iAmMaster) {
444 # remove reference counter lock
446 &simple_unlock
(&reffile
($filename),$timeout) or return;
448 # remove the write lock announce
450 &simple_unlock
($filename,$timeout) or return;
457 ### sub x_violent_unlock_file ($) ##############################################
459 # remove any lock violent (excl. master lock)
460 # (symlinks possible)
462 # Params: $filename - locked file
464 # Return: -none- (the success is not defined)
466 sub x_violent_unlock_file
($) {
469 unless (-l
&masterlockfile
($filename)) {
471 # find out last modification time
472 # and do nothing unless 'violent-timout' is over
476 if (-f
($reffile = $filename)) {
477 $time = (stat $reffile)[9];}
479 elsif (-l
($reffile = &lockfile
($filename))) {
480 $time = (lstat $reffile)[9];}
483 return if ((time - $time) < $violentTimeout);}
485 write_lock_file
($filename,1); # last try, to set an exclusive lock on $filename
486 unlink (&reffile
($filename)); # reference counter = 0
487 simple_unlock
(&reffile
($filename)); # release reference counter file
488 simple_unlock
($filename);} # release file
491 ### sub x_set_master_lock ($;$) ################################################
494 # (symlinks possible)
496 # Params: $filename - file to lock
497 # $timeout - timeout (sec.)
499 # Return: Status Code (Bool)
501 sub x_set_master_lock
($;$) {
502 my $filename = shift;
503 my $timeout = shift || $masterTimeout;
505 # set exclusive lock or fail
507 return unless (&write_lock_file
($filename,$timeout));
511 symlink $filename, &masterlockfile
($filename) and return 1;
513 # no chance (occupied?, master lock set yet?)
517 ### sub x_release_file ($) #####################################################
519 # remove any locks (incl. master lock)
520 # (symlinks possible)
522 # Params: $filename - file to lock
523 # $timeout - timeout (sec.)
525 # Return: Status Code (Bool)
527 sub x_release_file
($) {
530 unlink (&reffile
($filename)); # reference counter = 0
531 return if (-f
&reffile
($filename)); # really?
532 return unless (simple_unlock
(&reffile
($filename))); # release reference counter
533 return unless (&simple_unlock
($filename)); # remove any write lock announce
534 return unless (&simple_unlock
(&masterfile
($filename))); # remove master lock
540 ################################################################################
545 ### sub ~file ($) ##############################################################
547 # create lock file names
555 sub masterlockfile
($) {
556 &lockfile
(&masterfile
($_[0]));
562 ### sub w_simple_lock ($;$) ####################################################
563 ### sub w_simple_unlock ($) ####################################################
565 # simple file lock/unlock
566 # (for no-symlink-systems: kill/create lockfile)
568 # Params: $filename - file to lock
569 # [ $timeout - Lock time out (sec.) ]
571 # Return: Status Code (Bool)
573 sub w_simple_lock
($;$) {
574 my $filename = shift;
575 my $timeout = shift || $Timeout;
576 my $lockfile = lockfile
$filename;
579 unlink $lockfile and return 1;
588 sub w_simple_unlock
($) {
589 my $filename = shift;
590 my $lockfile = lockfile
$filename;
593 if (open(LF
, "> $lockfile")) {
594 return 1 if close (LF
);
597 # not able to create lockfile, hmmm...
602 ### sub w_simple_lock ($;$) ####################################################
603 ### sub w_simple_unlock ($) ####################################################
605 # simple file lock/unlock
606 # (symlinks possible: create/unlink symlink)
608 # Params: $filename - file to lock
609 # [ $timeout - Lock time out (sec.) ]
611 # Return: Status Code (Bool)
613 sub x_simple_lock
($;$) {
614 my $filename = shift;
615 my $timeout = shift || $Timeout;
616 my $lockfile = lockfile
$filename;
619 symlink $filename,$lockfile and return 1;
624 # locking failed (occupied?)
629 sub x_simple_unlock
($) {
632 unlink (&lockfile
($filename)) and return 1;
634 # not able to unlink symlink, hmmm...
639 ### sub w_set_ref ($$$) ########################################################
641 # add $_[1] to reference counter
642 # (may be negative...)
643 # (for no-symlink-systems)
645 # Params: $filename - file, reference counter belongs to
646 # $z - value, added to reference counter
647 # $timeout - lock time out
649 # Return: Status Code (Bool)
651 sub w_set_ref
($$$) {
652 my $filename = shift;
654 my $timeout = shift || $Timeout;
656 my $reffile = reffile
$filename;
659 # if write lock announced, only count down allowed
662 return unless(-f lockfile
($filename));
665 # lock reference counter file
667 return unless(&simple_lock
($reffile,$timeout));
669 # load reference counter
671 unless (open REF
,"<$reffile") {
680 # compute and write new ref. counter
683 $old = 0 if ($old < 0);
685 # kill reference counter file
686 # if ref. counter == 0
689 unlink $reffile or return;
692 open REF
,">$reffile" or return;
693 print REF
$old or return;
697 # release ref. counter file
699 return unless(&simple_unlock
($reffile));
705 ### sub x_set_ref ($$$) ########################################################
707 # add $_[1] to reference counter
708 # (may be negative...)
709 # (symlinks possible)
711 # Params: $filename - file, reference counter belongs to
712 # $z - value, added to reference counter
713 # $timeout - lock time out
715 # Return: Status Code (Bool)
717 sub x_set_ref
($$$) {
718 my $filename = shift;
720 my $timeout = shift || $Timeout;
722 my $reffile = reffile
$filename;
725 # if write lock announced, only count down allowed
728 return if(-l
&lockfile
($filename));
731 # lock reference counter file
733 return unless(&simple_lock
($reffile,$timeout));
735 # load reference counter
737 unless (open REF
,"<$reffile") {
746 # compute and write new ref. counter
749 $old = 0 if ($old < 0);
751 unlink $reffile or return;
754 open REF
,">$reffile" or return;
755 print REF
$old or return;
759 # release ref. counter file
761 return unless(&simple_unlock
($reffile));
767 ### sub get_ref ($) ############################################################
769 # read out the reference counter
770 # (system independant)
773 # Params: $filename - file, the ref. counter belongs to
775 # Return: reference counter
778 my $filename = shift;
779 my $reffile = reffile
$filename;
783 unless (open REF
,"< $reffile") {
796 ################################################################################
798 # initializing the module
801 # global variables (time in seconds)
803 $Timeout = 10; # normal timeout
804 $violentTimeout = 600; # violent timeout (10 minutes)
805 $masterTimeout = 20; # master timeout
807 $iAmMaster = 0; # default: I am nobody
809 # assign the aliases to the needed functions
810 # (perldoc -f symlink)
812 if ( eval {local $SIG{__DIE__
}; symlink('',''); 1 } ) {
813 *lock_file
= \
&x_lock_file
;
814 *unlock_file
= \
&x_unlock_file
;
815 *write_lock_file
= \
&x_write_lock_file
;
816 *write_unlock_file
= \
&x_write_unlock_file
;
817 *violent_unlock_file
= \
&x_violent_unlock_file
;
818 *set_master_lock
= \
&x_set_master_lock
;
819 *release_file
= \
&x_release_file
;
821 *simple_lock
= \
&x_simple_lock
;
822 *simple_unlock
= \
&x_simple_unlock
;
823 *set_ref
= \
&x_set_ref
;
827 *lock_file
= \
&w_lock_file
;
828 *unlock_file
= \
&w_unlock_file
;
829 *write_lock_file
= \
&w_write_lock_file
;
830 *write_unlock_file
= \
&w_write_unlock_file
;
831 *violent_unlock_file
= \
&w_violent_unlock_file
;
832 *set_master_lock
= \
&w_set_master_lock
;
833 *release_file
= \
&w_release_file
;
835 *simple_lock
= \
&w_simple_lock
;
836 *simple_unlock
= \
&w_simple_unlock
;
837 *set_ref
= \
&w_set_ref
;
841 # keeping require happy
846 ### end of Lock ################################################################
patrick-canterino.de