]>
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(@EXPORT_OK %EXPORT_TAGS $Timeout $violentTimeout $masterTimeout $iAmMaster);
17 # ====================================================
19 # ====================================================
21 use base qw(Exporter);
23 @EXPORT_OK = qw(lock_file unlock_file write_lock_file write_unlock_file
24 violent_unlock_file set_master_lock release_file);
26 %EXPORT_TAGS = (READ
=> [qw(lock_file unlock_file violent_unlock_file)],
27 WRITE
=> [qw(write_lock_file write_unlock_file violent_unlock_file)],
28 ALL
=> [qw(lock_file unlock_file write_lock_file write_unlock_file
29 violent_unlock_file set_master_lock release_file)]);
31 # ====================================================
32 # Windows section (no symlinks)
33 # ====================================================
35 ################################
38 # Schreibsperre setzen
39 ################################
41 sub w_lock_file
($;$) {
43 my ($timeout)=(shift (@_) or $Timeout);
46 if (-f
&masterlockfile
($filename)) {
48 for ($i=0 ; $i<=$timeout ; $i++) {
49 # Referenzzaehler um eins erhoehen
50 &set_ref
($filename,1,$timeout) and return 1;
60 ################################
63 # Schreibsperre aufheben
64 ################################
66 sub w_unlock_file
($;$) {
68 my ($timeout)=(shift (@_) or $Timeout);
70 if (-f
&masterlockfile
($filename)) {
71 # Referenzzaehler um eins erniedrigen
72 &set_ref
($filename,-1,$timeout) and return 1;}
77 ################################
78 # sub w_write_lock_file
80 # Lese- und Schreibsperre
82 ################################
84 sub w_write_lock_file
($;$) {
86 my ($timeout)=(shift (@_) or $Timeout);
88 if (-f
&masterlockfile
($filename) or $iAmMaster) {
89 # bevorstehenden Schreibzugriff anmelden
90 &simple_lock
($filename,$timeout) or return 0;
93 for ($i=0 ; $i<=$timeout ; $i++) {
94 # Referenzdatei sperren
95 &simple_lock
(&reffile
($filename),$timeout) or (return &simple_unlock
($filename,$timeout) and 0);
97 # Referenzzaehler = 0 ? => okay
98 return 1 if (&get_ref
($filename) == 0);
100 # Referenzdatei wieder freigeben
101 &simple_unlock
(&reffile
($filename),$timeout) or (return &simple_unlock
($filename,$timeout) and 0);
104 &simple_unlock
($filename);}
107 # Mastersperre gesetzt
113 ################################
114 # sub w_write_unlock_file
116 # Lese- und Schreibsperre
118 ################################
120 sub w_write_unlock_file
($;$) {
122 my ($timeout)=(shift (@_) or $Timeout);
124 if (-f
&masterlockfile
($filename) or $iAmMaster) {
125 &simple_unlock
(&reffile
($filename),$timeout) or return 0; # Referenzdatei freigeben
126 &simple_unlock
($filename,$timeout) or return 0;} # Lesesperre aufheben
131 ################################
132 # sub w_violent_unlock_file
134 # Sperre brutal aufheben
135 ################################
137 sub w_violent_unlock_file
($) {
140 if (-f
&masterlockfile
($filename)) {
142 # Zeit der letzten Modifikation feststellen
143 # und abbrechen, wenn meine Zeit noch nicht gekommen ist
145 if (-f
($reffile = $filename) or -f
($reffile = &lockfile
($filename))) {
146 my $time = (stat $reffile)[9];
147 return if ((time - $time) < $violentTimeout);}
149 write_lock_file
($filename,1); # letzter Versuch, exklusiven Zugriff zu bekommen
150 unlink (&reffile
($filename)); # Referenzzaehler auf null
151 simple_unlock
(&reffile
($filename)); # Referenzdatei freigeben
152 simple_unlock
($filename);} # Datei freigeben (Lesesperre aufheben)
155 ################################
156 # sub w_set_master_lock
158 # Mastersperre setzen
159 ################################
161 sub w_set_master_lock
($;$) {
163 my $timeout=(shift @_ or $masterTimeout);
165 # exklusiven Zugriff erlangen...oder abbrechen
166 return 0 unless (&write_lock_file
($filename,$timeout));
168 # Mastersperre setzen und Erfolg melden
169 unlink &masterlockfile
($filename) and return 1;
174 ################################
177 # Alle Sperren inkl. Master-
179 ################################
181 sub w_release_file
($) {
184 unlink (&reffile
($filename)); # Referenzzaehler auf null
185 return 0 if (-f
&reffile
($filename)); # wirklich?
186 return 0 unless (simple_unlock
(&reffile
($filename))); # Referenzzaehler freigeben
187 return 0 unless (&simple_unlock
($filename)); # Datei selbst freigeben (Lesesperre)
188 return 0 unless (&simple_unlock
(&masterfile
($filename))); # Mastersperre aufheben
193 # ====================================================
194 # *n*x section (symlinks possible)
195 # ====================================================
197 ################################
200 # Schreibsperre setzen
201 ################################
203 sub x_lock_file
($;$) {
205 my ($timeout)=(shift (@_) or $Timeout);
208 unless (-l
&masterlockfile
($filename)) {
210 for ($i=0 ; $i<=$timeout ; $i++) {
211 # Referenzzaehler um eins erhoehen
212 &set_ref
($filename,1,$timeout) and return 1;
222 ################################
225 # Schreibsperre aufheben
226 ################################
228 sub x_unlock_file
($;$) {
230 my ($timeout)=(shift (@_) or $Timeout);
232 unless (-l
&masterlockfile
($filename)) {
233 # Referenzzaehler um eins erniedrigen
234 &set_ref
($filename,-1,$timeout) and return 1;}
239 ################################
240 # sub x_write_lock_file
242 # Lese- und Schreibsperre
244 ################################
246 sub x_write_lock_file
($;$) {
248 my ($timeout)=(shift (@_) or $Timeout);
250 unless (-l
&masterlockfile
($filename) and not $iAmMaster) {
251 # bevorstehenden Schreibzugriff anmelden
252 &simple_lock
($filename,$timeout) or return 0;
255 for ($i=0 ; $i<=$timeout ; $i++) {
256 # Referenzdatei sperren
257 &simple_lock
(&reffile
($filename),$timeout) or (return &simple_unlock
($filename,$timeout) and 0);
259 # Referenzzaehler = 0 ? => okay
260 return 1 if (&get_ref
($filename) == 0);
262 # Referenzdatei wieder freigeben
263 &simple_unlock
(&reffile
($filename),$timeout) or (return &simple_unlock
($filename,$timeout) and 0);
266 &simple_unlock
($filename);}
269 # Mastersperre gesetzt
275 ################################
276 # sub x_write_unlock_file
278 # Lese- und Schreibsperre
280 ################################
282 sub x_write_unlock_file
($;$) {
284 my ($timeout)=(shift (@_) or $Timeout);
286 unless (-l
&masterlockfile
($filename) and not $iAmMaster) {
287 &simple_unlock
(&reffile
($filename),$timeout) or return 0; # Referenzdatei freigeben
288 &simple_unlock
($filename,$timeout) or return 0;} # Lesesperre aufheben
293 ################################
294 # sub x_violent_unlock_file
296 # Sperre brutal aufheben
297 ################################
299 sub x_violent_unlock_file
($) {
302 unless (-l
&masterlockfile
($filename)) {
304 # Zeit der letzten Modifikation feststellen
305 # und abbrechen, wenn meine Zeit noch nicht gekommen ist
308 if (-f
($reffile = $filename)) {
309 $time = (stat $reffile)[9];}
311 elsif (-l
($reffile = &lockfile
($filename))) {
312 $time = (lstat $reffile)[9];}
315 return if ((time - $time) < $violentTimeout);}
317 write_lock_file
($filename,1); # letzter Versuch, exklusiven Zugriff zu bekommen
318 unlink (&reffile
($filename)); # Referenzzaehler auf null
319 simple_unlock
(&reffile
($filename)); # Referenzdatei freigeben
320 simple_unlock
($filename);} # Datei freigeben (Lesesperre aufheben)
323 ################################
324 # sub x_set_master_lock
326 # Mastersperre setzen
327 ################################
329 sub x_set_master_lock
($;$) {
331 my $timeout=(shift @_ or $masterTimeout);
333 # exklusiven Zugriff erlangen...oder abbrechen
334 return 0 unless (&write_lock_file
($filename,$timeout));
336 # Mastersperre setzen und Erfolg melden
337 symlink $filename, &masterlockfile
($filename) and return 1;
342 ################################
345 # Alle Sperren inkl. Master-
347 ################################
349 sub x_release_file
($) {
352 unlink (&reffile
($filename)); # Referenzzaehler auf null
353 return 0 if (-f
&reffile
($filename)); # wirklich?
354 return 0 unless (simple_unlock
(&reffile
($filename))); # Referenzzaehler freigeben
355 return 0 unless (&simple_unlock
($filename)); # Datei selbst freigeben (Lesesperre)
356 return 0 unless (&simple_unlock
(&masterfile
($filename))); # Mastersperre aufheben
361 # ====================================================
363 # ====================================================
365 ################################
367 ################################
375 sub masterlockfile
($) {
376 &lockfile
(&masterfile
($_[0]));
382 ################################
383 # einfaches Sperren/Entsperren
386 # (Lockdatei loeschen)
387 ################################
389 sub w_simple_lock
($;$) {
391 my ($timeout)=(shift (@_) or $Timeout);
392 my $lockfile=&lockfile
($filename);
395 for ($i=$timeout; $i>=0; $i--) {
396 unlink("$lockfile") and return 1;
402 sub w_simple_unlock
($) {
404 my $lockfile=&lockfile
($filename);
408 open(LF
, ">$lockfile") or $flag=0;
409 close(LF
) or $flag=0;
415 ################################
416 # einfaches Sperren/Entsperren
420 ################################
422 sub x_simple_lock
($;$) {
424 my ($timeout)=(shift (@_) or $Timeout);
425 my $lockfile=&lockfile
($filename);
428 for ($i=$timeout; $i>=0; $i--) {
429 symlink $filename,$lockfile and return 1;
435 sub x_simple_unlock
($) {
438 unlink (&lockfile
($filename)) and return 1;
443 ################################
447 # Referenzzaehler um $_[1]
449 # (kann auch negativ sein...)
450 ################################
452 sub w_set_ref
($$$) {
453 my ($filename,$z)=@_;
454 my $timeout=(shift @_ or $Timeout);
456 my $reffile=&reffile
($filename);
460 # runterzaehlen - ja, neue Leseversuche - nein
462 return 0 unless(-e
&lockfile
($filename));}
464 # Referenzdatei locken
465 return 0 unless(&simple_lock
($reffile,$timeout));
467 # Referenzdatei auslesen
468 unless (open REF
,"<$reffile") {
473 close REF
or return 0;}
475 # Neuen Referenzwert schreiben
477 $old=0 if ($old < 0);
480 unlink $reffile or return 0;
484 open REF
,">$reffile" or return 0;
485 print REF
$old or return 0;
486 close REF
or return 0;
490 return 0 unless(&simple_unlock
($reffile));
495 ################################
499 # Referenzzaehler um $_[1]
501 # (kann auch negativ sein...)
502 ################################
504 sub x_set_ref
($$$) {
505 my ($filename,$z)=@_;
506 my $timeout=(shift @_ or $Timeout);
508 my $reffile=&reffile
($filename);
512 # runterzaehlen - ja, neue Leseversuche - nein
514 return 0 if(-l
&lockfile
($filename));}
516 # Referenzdatei locken
517 return 0 unless(&simple_lock
($reffile,$timeout));
519 # Referenzdatei auslesen
520 unless (open REF
,"<$reffile") {
525 close REF
or return 0;}
527 # Neuen Referenzwert schreiben
529 $old = 0 if ($old < 0);
532 unlink $reffile or return 0;
536 open REF
,">$reffile" or return 0;
537 print REF
$old or return 0;
538 close REF
or return 0;
542 return 0 unless(&simple_unlock
($reffile));
547 ################################
550 # Referenzzaehler auslesen
552 # Das Locking muss an
553 # anderer Stelle ausgefuehrt
555 ################################
559 my $reffile=&reffile
($filename);
563 unless (open REF
,"<$reffile") {
568 close REF
or return 0;}
574 # ====================================================
575 # Modulinitialisierung
576 # ====================================================
579 # Globale Variablen (Zeiten in Sekunden)
580 $Timeout = 10; # normaler Timeout
581 $violentTimeout = 600; # zum gewaltsamen Entsperren (10 Minuten)
582 $masterTimeout = 20; # fuer die Mastersperre
584 $iAmMaster = 0; # erstmal bin ich kein Master :-)
586 # wirkliche Funktionen ihren Bezeichnern zuweisen
587 # (perldoc -f symlink)
589 if ( eval {local $SIG{__DIE__
}; symlink('',''); 1 } ) {
590 *lock_file
= \
&x_lock_file
;
591 *unlock_file
= \
&x_unlock_file
;
592 *write_lock_file
= \
&x_write_lock_file
;
593 *write_unlock_file
= \
&x_write_unlock_file
;
594 *violent_unlock_file
= \
&x_violent_unlock_file
;
595 *set_master_lock
= \
&x_set_master_lock
;
596 *release_file
= \
&x_release_file
;
598 *simple_lock
= \
&x_simple_lock
;
599 *simple_unlock
= \
&x_simple_unlock
;
600 *set_ref
= \
&x_set_ref
;}
603 *lock_file
= \
&w_lock_file
;
604 *unlock_file
= \
&w_unlock_file
;
605 *write_lock_file
= \
&w_write_lock_file
;
606 *write_unlock_file
= \
&w_write_unlock_file
;
607 *violent_unlock_file
= \
&w_violent_unlock_file
;
608 *set_master_lock
= \
&w_set_master_lock
;
609 *release_file
= \
&w_release_file
;
611 *simple_lock
= \
&w_simple_lock
;
612 *simple_unlock
= \
&w_simple_unlock
;
613 *set_ref
= \
&w_set_ref
;}
616 # making require happy
619 # ====================================================
621 # ====================================================
patrick-canterino.de