]>
git.p6c8.net - selfforum.git/blob - selfforum-cgi/shared/Lock/API.pm
3 ################################################################################
5 # File: shared/Lock/API.pm #
7 # Authors: Andre Malo <nd@o3media.de>, 2001-05-25 #
9 # Description: system independent part of Locking and Filehandle class #
10 # NOT FOR PUBLIC USE #
12 ################################################################################
26 ################################################################################
30 $VERSION = do { my @r =(q
$Revision$ =~ /\d+/g); sprintf "%d."."%02d" x
$#r, @r };
32 ### sub lock ###################################################################
34 # set a lock on the file
36 # Params: $locktype - what kind of locking?
37 # $timeout - (optional) Timeout
39 # Return: success (boolean)
45 return if $self -> masterlocked
;
47 ###########################################
50 if ($locktype == $self -> LH_SHARED
) {
51 return 1 if $self -> locked_shared
;
52 return if $self -> locked_exclusive
;
54 my $timeout = shift || $self -> timeout
('shared');
56 # try to increase the reference counter
58 if ($self -> add_ref
($timeout)) {
59 $self -> set_static
(locked_shared
=> 1);
65 ###########################################
68 elsif ($locktype == $self -> LH_EXCL
) {
69 return 1 if $self -> locked_exclusive
;
71 my $timeout = shift || $self -> timeout
('exclusive');
74 # transform exclusive shared lock into exclusive lock
76 if ($self -> locked_exsh
) {
77 my $reflock = new Lock
::Handle
($self -> reflock
);
80 if ($self -> set_excl_announce
and $self -> _simple_lock
($reflock)) {
81 if ($self -> get_ref
== 1) {
83 $self -> remove_exsh_announce
;
84 $self -> set_static
(locked_exsh
=> 0);
85 $self -> set_static
(locked_exclusive
=> 1);
89 last unless ($self -> _simple_unlock
($reflock->filename));
94 $self -> remove_excl_announce
;
101 my $reflock = new Lock
::Handle
($self -> reflock
);
104 if ($self -> set_excl_announce
and $self -> _simple_lock
($reflock)) {
105 if ($self -> get_ref
== 0) {
106 $self -> set_static
(locked_exclusive
=> 1);
110 last unless ($self -> _simple_unlock
($reflock->filename));
115 $self -> remove_excl_announce
;
120 ###########################################
121 # exclusive shared lock
123 elsif ($locktype == $self -> LH_EXSH
) {
124 return 1 if $self -> locked_exsh
;
125 return if ($self -> locked_shared
or $self -> locked_exclusive
);
127 my $timeout = shift || $self -> timeout
('shared');
129 # try to increase the reference counter
131 if ($self -> es_add_ref
($timeout)) {
132 $self -> set_static
(locked_exsh
=> 1);
138 ###########################################
141 elsif ($locktype == $self -> LH_MASTER
) {
142 $self -> lock ($self->LH_EXCL, $self -> timeout
('master')) and
143 $self -> _simple_lock
(new Lock
::Handle
($self->masterlock)) and
147 ###########################################
148 # unknown locking type
151 croak
"unknown locking type '$locktype'";
156 $self -> unlock_violent
;
160 ### sub unlock #################################################################
162 # remove shared or exclusive lock
164 # Params: $timeout - (optional) Timeout
166 # Return: success (boolean)
170 my $timeout = shift || $self -> timeout
('shared');
172 return if $self -> masterlocked
;
174 ###########################################
177 if ($self -> locked_shared
) {
178 # try to decrease the reference counter
180 if ($self -> sub_ref
($timeout)) {
181 $self -> set_static
(locked_shared
=> 0);
187 ###########################################
190 elsif ($self -> locked_exclusive
) {
191 my $reflock = new Lock
::Handle
($self -> reflock
);
194 if ($self -> _simple_unlock
($reflock->filename)) {
195 $self -> remove_excl_announce
;
196 $self -> set_static
(locked_exclusive
=> 0);
205 ###########################################
206 # exclusive shared lock
208 elsif ($self -> locked_exsh
) {
209 # try to decrease the reference counter
211 if ($self -> es_sub_ref
($timeout)) {
212 $self -> remove_exsh_announce
;
213 $self -> set_static
(locked_exsh
=> 0);
219 ###########################################
228 $self -> unlock_violent
;
232 ### sub unlock_violent #########################################################
234 # remove any lock violently (excludes master lock)
238 # Return: -none- (the success is undefined)
243 unless ($self -> masterlocked
) {
245 # find out last modification time
246 # and do nothing unless 'violent-timout' is over
248 my $time = $self -> _reftime
;
251 return if ((time - $time) < $self -> timeout
('violent'));
254 $self -> set_ref
(0); # reference counter = 0
255 $self -> _simple_unlock
($self -> reflock
); # release reference counter file
256 $self -> _simple_unlock
($self -> exshlock
); # remove excl shared lock
257 $self -> _simple_unlock
($self -> lockfile
); # release file
263 ### sub release ################################################################
274 $self -> set_ref
(0); # reference counter = 0
275 $self -> _simple_unlock
($self -> reflock
); # release reference counter
276 $self -> _simple_unlock
($self -> lockfile
); # remove any write lock announce
277 $self -> _simple_unlock
($self -> exshlock
); # remove any excl shared lock
278 $self -> _simple_unlock
($self -> masterlock
); # remove master lock
283 # keep 'require' happy
288 ### end of Lock::API ###########################################################
patrick-canterino.de