]>
git.p6c8.net - selfforum.git/blob - selfforum-cgi/shared/Lock.pm
b1e42d37120dff29660152d1f7ca0f8da205e763
3 # ====================================================
4 # Autor: n.d.p. / 2001-01-04
5 # lm : n.d.p. / 2000-01-05
6 # ====================================================
9 # ====================================================
15 use vars
qw(@ISA @EXPORT_OK %EXPORT_TAGS $Timeout $violentTimeout $masterTimeout $iAmMaster);
17 # ====================================================
19 # ====================================================
24 @EXPORT_OK = qw(lock_file unlock_file write_lock_file write_unlock_file
25 violent_unlock_file set_master_lock release_file);
27 %EXPORT_TAGS = (READ
=> [qw(lock_file unlock_file violent_unlock_file)],
28 WRITE
=> [qw(write_lock_file write_unlock_file violent_unlock_file)],
29 ALL
=> [qw(lock_file unlock_file write_lock_file write_unlock_file
30 violent_unlock_file set_master_lock release_file)]);
32 # ====================================================
33 # Windows section (no symlinks)
34 # ====================================================
36 ################################
39 # Schreibsperre setzen
40 ################################
42 sub w_lock_file
($;$) {
44 my ($timeout)=(shift (@_) or $Timeout);
47 if (-f
&masterlockfile
($filename)) {
49 for ($i=0 ; $i<=$timeout ; $i++) {
50 # Referenzzaehler um eins erhoehen
51 &set_ref
($filename,1,$timeout) and return 1;
61 ################################
64 # Schreibsperre aufheben
65 ################################
67 sub w_unlock_file
($;$) {
69 my ($timeout)=(shift (@_) or $Timeout);
71 if (-f
&masterlockfile
($filename)) {
72 # Referenzzaehler um eins erniedrigen
73 &set_ref
($filename,-1,$timeout) and return 1;}
78 ################################
79 # sub w_write_lock_file
81 # Lese- und Schreibsperre
83 ################################
85 sub w_write_lock_file
($;$) {
87 my ($timeout)=(shift (@_) or $Timeout);
89 if (-f
&masterlockfile
($filename) or $iAmMaster) {
90 # bevorstehenden Schreibzugriff anmelden
91 &simple_lock
($filename,$timeout) or return 0;
94 for ($i=0 ; $i<=$timeout ; $i++) {
95 # Referenzdatei sperren
96 &simple_lock
(&reffile
($filename),$timeout) or (return &simple_unlock
($filename,$timeout) and 0);
98 # Referenzzaehler = 0 ? => okay
99 return 1 if (&get_ref
($filename) == 0);
101 # Referenzdatei wieder freigeben
102 &simple_unlock
(&reffile
($filename),$timeout) or (return &simple_unlock
($filename,$timeout) and 0);
105 &simple_unlock
($filename);}
108 # Mastersperre gesetzt
114 ################################
115 # sub w_write_unlock_file
117 # Lese- und Schreibsperre
119 ################################
121 sub w_write_unlock_file
($;$) {
123 my ($timeout)=(shift (@_) or $Timeout);
125 if (-f
&masterlockfile
($filename) or $iAmMaster) {
126 &simple_unlock
(&reffile
($filename),$timeout) or return 0; # Referenzdatei freigeben
127 &simple_unlock
($filename,$timeout) or return 0;} # Lesesperre aufheben
132 ################################
133 # sub w_violent_unlock_file
135 # Sperre brutal aufheben
136 ################################
138 sub w_violent_unlock_file
($) {
141 if (-f
&masterlockfile
($filename)) {
143 # Zeit der letzten Modifikation feststellen
144 # und abbrechen, wenn meine Zeit noch nicht gekommen ist
146 if (-f
($reffile = $filename) or -f
($reffile = &lockfile
($filename))) {
147 my $time = (stat $reffile)[9];
148 return if ((time - $time) < $violentTimeout);}
150 write_lock_file
($filename,1); # letzter Versuch, exklusiven Zugriff zu bekommen
151 unlink (&reffile
($filename)); # Referenzzaehler auf null
152 simple_unlock
(&reffile
($filename)); # Referenzdatei freigeben
153 simple_unlock
($filename);} # Datei freigeben (Lesesperre aufheben)
156 ################################
157 # sub w_set_master_lock
159 # Mastersperre setzen
160 ################################
162 sub w_set_master_lock
($;$) {
164 my $timeout=(shift @_ or $masterTimeout);
166 # exklusiven Zugriff erlangen...oder abbrechen
167 return 0 unless (&write_lock_file
($filename,$timeout));
169 # Mastersperre setzen und Erfolg melden
170 unlink &masterlockfile
($filename) and return 1;
175 ################################
178 # Alle Sperren inkl. Master-
180 ################################
182 sub w_release_file
($) {
185 unlink (&reffile
($filename)); # Referenzzaehler auf null
186 return 0 if (-f
&reffile
($filename)); # wirklich?
187 return 0 unless (simple_unlock
(&reffile
($filename))); # Referenzzaehler freigeben
188 return 0 unless (&simple_unlock
($filename)); # Datei selbst freigeben (Lesesperre)
189 return 0 unless (&simple_unlock
(&masterfile
($filename))); # Mastersperre aufheben
194 # ====================================================
195 # *n*x section (symlinks possible)
196 # ====================================================
198 ################################
201 # Schreibsperre setzen
202 ################################
204 sub x_lock_file
($;$) {
206 my ($timeout)=(shift (@_) or $Timeout);
209 unless (-l
&masterlockfile
($filename)) {
211 for ($i=0 ; $i<=$timeout ; $i++) {
212 # Referenzzaehler um eins erhoehen
213 &set_ref
($filename,1,$timeout) and return 1;
223 ################################
226 # Schreibsperre aufheben
227 ################################
229 sub x_unlock_file
($;$) {
231 my ($timeout)=(shift (@_) or $Timeout);
233 unless (-l
&masterlockfile
($filename)) {
234 # Referenzzaehler um eins erniedrigen
235 &set_ref
($filename,-1,$timeout) and return 1;}
240 ################################
241 # sub x_write_lock_file
243 # Lese- und Schreibsperre
245 ################################
247 sub x_write_lock_file
($;$) {
249 my ($timeout)=(shift (@_) or $Timeout);
251 unless (-l
&masterlockfile
($filename) and not $iAmMaster) {
252 # bevorstehenden Schreibzugriff anmelden
253 &simple_lock
($filename,$timeout) or return 0;
256 for ($i=0 ; $i<=$timeout ; $i++) {
257 # Referenzdatei sperren
258 &simple_lock
(&reffile
($filename),$timeout) or (return &simple_unlock
($filename,$timeout) and 0);
260 # Referenzzaehler = 0 ? => okay
261 return 1 if (&get_ref
($filename) == 0);
263 # Referenzdatei wieder freigeben
264 &simple_unlock
(&reffile
($filename),$timeout) or (return &simple_unlock
($filename,$timeout) and 0);
267 &simple_unlock
($filename);}
270 # Mastersperre gesetzt
276 ################################
277 # sub x_write_unlock_file
279 # Lese- und Schreibsperre
281 ################################
283 sub x_write_unlock_file
($;$) {
285 my ($timeout)=(shift (@_) or $Timeout);
287 unless (-l
&masterlockfile
($filename) and not $iAmMaster) {
288 &simple_unlock
(&reffile
($filename),$timeout) or return 0; # Referenzdatei freigeben
289 &simple_unlock
($filename,$timeout) or return 0;} # Lesesperre aufheben
294 ################################
295 # sub x_violent_unlock_file
297 # Sperre brutal aufheben
298 ################################
300 sub x_violent_unlock_file
($) {
303 unless (-l
&masterlockfile
($filename)) {
305 # Zeit der letzten Modifikation feststellen
306 # und abbrechen, wenn meine Zeit noch nicht gekommen ist
309 if (-f
($reffile = $filename)) {
310 $time = (stat $reffile)[9];}
312 elsif (-l
($reffile = &lockfile
($filename))) {
313 $time = (lstat $reffile)[9];}
316 return if ((time - $time) < $violentTimeout);}
318 write_lock_file
($filename,1); # letzter Versuch, exklusiven Zugriff zu bekommen
319 unlink (&reffile
($filename)); # Referenzzaehler auf null
320 simple_unlock
(&reffile
($filename)); # Referenzdatei freigeben
321 simple_unlock
($filename);} # Datei freigeben (Lesesperre aufheben)
324 ################################
325 # sub x_set_master_lock
327 # Mastersperre setzen
328 ################################
330 sub x_set_master_lock
($;$) {
332 my $timeout=(shift @_ or $masterTimeout);
334 # exklusiven Zugriff erlangen...oder abbrechen
335 return 0 unless (&write_lock_file
($filename,$timeout));
337 # Mastersperre setzen und Erfolg melden
338 symlink $filename, &masterlockfile
($filename) and return 1;
343 ################################
346 # Alle Sperren inkl. Master-
348 ################################
350 sub x_release_file
($) {
353 unlink (&reffile
($filename)); # Referenzzaehler auf null
354 return 0 if (-f
&reffile
($filename)); # wirklich?
355 return 0 unless (simple_unlock
(&reffile
($filename))); # Referenzzaehler freigeben
356 return 0 unless (&simple_unlock
($filename)); # Datei selbst freigeben (Lesesperre)
357 return 0 unless (&simple_unlock
(&masterfile
($filename))); # Mastersperre aufheben
362 # ====================================================
364 # ====================================================
366 ################################
368 ################################
376 sub masterlockfile
($) {
377 &lockfile
(&masterfile
($_[0]));
383 ################################
384 # einfaches Sperren/Entsperren
387 # (Lockdatei loeschen)
388 ################################
390 sub w_simple_lock
($;$) {
392 my ($timeout)=(shift (@_) or $Timeout);
393 my $lockfile=&lockfile
($filename);
396 for ($i=$timeout; $i>=0; $i--) {
397 unlink("$lockfile") and return 1;
403 sub w_simple_unlock
($) {
405 my $lockfile=&lockfile
($filename);
409 open(LF
, ">$lockfile") or $flag=0;
410 close(LF
) or $flag=0;
416 ################################
417 # einfaches Sperren/Entsperren
421 ################################
423 sub x_simple_lock
($;$) {
425 my ($timeout)=(shift (@_) or $Timeout);
426 my $lockfile=&lockfile
($filename);
429 for ($i=$timeout; $i>=0; $i--) {
430 symlink $filename,$lockfile and return 1;
436 sub x_simple_unlock
($) {
439 unlink (&lockfile
($filename)) and return 1;
444 ################################
448 # Referenzzaehler um $_[1]
450 # (kann auch negativ sein...)
451 ################################
453 sub w_set_ref
($$$) {
454 my ($filename,$z)=@_;
455 my $timeout=(shift @_ or $Timeout);
457 my $reffile=&reffile
($filename);
461 # runterzaehlen - ja, neue Leseversuche - nein
463 return 0 unless(-e
&lockfile
($filename));}
465 # Referenzdatei locken
466 return 0 unless(&simple_lock
($reffile,$timeout));
468 # Referenzdatei auslesen
469 unless (open REF
,"<$reffile") {
474 close REF
or return 0;}
476 # Neuen Referenzwert schreiben
478 $old=0 if ($old < 0);
481 unlink $reffile or return 0;
485 open REF
,">$reffile" or return 0;
486 print REF
$old or return 0;
487 close REF
or return 0;
491 return 0 unless(&simple_unlock
($reffile));
496 ################################
500 # Referenzzaehler um $_[1]
502 # (kann auch negativ sein...)
503 ################################
505 sub x_set_ref
($$$) {
506 my ($filename,$z)=@_;
507 my $timeout=(shift @_ or $Timeout);
509 my $reffile=&reffile
($filename);
513 # runterzaehlen - ja, neue Leseversuche - nein
515 return 0 if(-l
&lockfile
($filename));}
517 # Referenzdatei locken
518 return 0 unless(&simple_lock
($reffile,$timeout));
520 # Referenzdatei auslesen
521 unless (open REF
,"<$reffile") {
526 close REF
or return 0;}
528 # Neuen Referenzwert schreiben
530 $old = 0 if ($old < 0);
533 unlink $reffile or return 0;
537 open REF
,">$reffile" or return 0;
538 print REF
$old or return 0;
539 close REF
or return 0;
543 return 0 unless(&simple_unlock
($reffile));
548 ################################
551 # Referenzzaehler auslesen
553 # Das Locking muss an
554 # anderer Stelle ausgefuehrt
556 ################################
560 my $reffile=&reffile
($filename);
564 unless (open REF
,"<$reffile") {
569 close REF
or return 0;}
575 # ====================================================
576 # Modulinitialisierung
577 # ====================================================
580 # Globale Variablen (Zeiten in Sekunden)
581 $Timeout = 10; # normaler Timeout
582 $violentTimeout = 600; # zum gewaltsamen Entsperren (10 Minuten)
583 $masterTimeout = 20; # fuer die Mastersperre
585 $iAmMaster = 0; # erstmal bin ich kein Master :-)
587 # wirkliche Funktionen ihren Bezeichnern zuweisen
588 # (perldoc -f symlink)
590 if ( eval {local $SIG{__DIE__
}; symlink('',''); 1 } ) {
591 *lock_file
= \
&x_lock_file
;
592 *unlock_file
= \
&x_unlock_file
;
593 *write_lock_file
= \
&x_write_lock_file
;
594 *write_unlock_file
= \
&x_write_unlock_file
;
595 *violent_unlock_file
= \
&x_violent_unlock_file
;
596 *set_master_lock
= \
&x_set_master_lock
;
597 *release_file
= \
&x_release_file
;
599 *simple_lock
= \
&x_simple_lock
;
600 *simple_unlock
= \
&x_simple_unlock
;
601 *set_ref
= \
&x_set_ref
;}
604 *lock_file
= \
&w_lock_file
;
605 *unlock_file
= \
&w_unlock_file
;
606 *write_lock_file
= \
&w_write_lock_file
;
607 *write_unlock_file
= \
&w_write_unlock_file
;
608 *violent_unlock_file
= \
&w_violent_unlock_file
;
609 *set_master_lock
= \
&w_set_master_lock
;
610 *release_file
= \
&w_release_file
;
612 *simple_lock
= \
&w_simple_lock
;
613 *simple_unlock
= \
&w_simple_unlock
;
614 *set_ref
= \
&w_set_ref
;}
617 # making require happy
620 # ====================================================
622 # ====================================================
patrick-canterino.de