]>
git.p6c8.net - selfforum.git/blob - selfforum-cgi/shared/Lock.pm
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);
479 open REF
,">$reffile" or return 0;
481 close REF
or return 0;
484 return 0 unless(&simple_unlock
($reffile));
489 ################################
493 # Referenzzaehler um $_[1]
495 # (kann auch negativ sein...)
496 ################################
498 sub x_set_ref
($$$) {
499 my ($filename,$z)=@_;
500 my $timeout=(shift @_ or $Timeout);
502 my $reffile=&reffile
($filename);
506 # runterzaehlen - ja, neue Leseversuche - nein
508 return 0 if(-l
&lockfile
($filename));}
510 # Referenzdatei locken
511 return 0 unless(&simple_lock
($reffile,$timeout));
513 # Referenzdatei auslesen
514 unless (open REF
,"<$reffile") {
519 close REF
or return 0;}
521 # Neuen Referenzwert schreiben
523 $old = 0 if ($old < 0);
524 open REF
,">$reffile" or return 0;
526 close REF
or return 0;
529 return 0 unless(&simple_unlock
($reffile));
534 ################################
537 # Referenzzaehler auslesen
539 # Das Locking muss an
540 # anderer Stelle ausgefuehrt
542 ################################
546 my $reffile=&reffile
($filename);
550 unless (open REF
,"<$reffile") {
555 close REF
or return 0;}
561 # ====================================================
562 # Modulinitialisierung
563 # ====================================================
566 # Globale Variablen (Zeiten in Sekunden)
567 $Timeout = 10; # normaler Timeout
568 $violentTimeout = 600; # zum gewaltsamen Entsperren (10 Minuten)
569 $masterTimeout = 20; # fuer die Mastersperre
571 $iAmMaster = 0; # erstmal bin ich kein Master :-)
573 # wirkliche Funktionen ihren Bezeichnern zuweisen
574 # (perldoc -f symlink)
576 if ( eval {local $SIG{__DIE__
}; symlink('',''); 1 } ) {
577 *lock_file
= \
&x_lock_file
;
578 *unlock_file
= \
&x_unlock_file
;
579 *write_lock_file
= \
&x_write_lock_file
;
580 *write_unlock_file
= \
&x_write_unlock_file
;
581 *violent_unlock_file
= \
&x_violent_unlock_file
;
582 *set_master_lock
= \
&x_set_master_lock
;
583 *release_file
= \
&x_release_file
;
585 *simple_lock
= \
&x_simple_lock
;
586 *simple_unlock
= \
&x_simple_unlock
;
587 *set_ref
= \
&x_set_ref
;}
590 *lock_file
= \
&w_lock_file
;
591 *unlock_file
= \
&w_unlock_file
;
592 *write_lock_file
= \
&w_write_lock_file
;
593 *write_unlock_file
= \
&w_write_unlock_file
;
594 *violent_unlock_file
= \
&w_violent_unlock_file
;
595 *set_master_lock
= \
&w_set_master_lock
;
596 *release_file
= \
&w_release_file
;
598 *simple_lock
= \
&w_simple_lock
;
599 *simple_unlock
= \
&w_simple_unlock
;
600 *set_ref
= \
&w_set_ref
;}
603 # making require happy
606 # ====================================================
608 # ====================================================
patrick-canterino.de