]>
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 # VERY violent way to set master lock
151 $self -> lock ($self->LH_EXCL, $self -> timeout
('master')) and
152 $self -> _simple_lock
(new Lock
::Handle
($self->masterlock)) and
156 ###########################################
157 # unknown locking type
160 croak
"unknown locking type '$locktype'";
165 $self -> unlock_violent
;
169 ### sub unlock #################################################################
171 # remove shared or exclusive lock
173 # Params: $timeout - (optional) Timeout
175 # Return: success (boolean)
179 my $timeout = shift || $self -> timeout
('shared');
181 return if $self -> masterlocked
;
183 ###########################################
186 if ($self -> locked_shared
) {
187 # try to decrease the reference counter
189 if ($self -> sub_ref
($timeout)) {
190 $self -> set_static
(locked_shared
=> 0);
196 ###########################################
199 elsif ($self -> locked_exclusive
) {
200 my $reflock = new Lock
::Handle
($self -> reflock
);
203 if ($self -> _simple_unlock
($reflock->filename)) {
204 $self -> remove_excl_announce
;
205 $self -> set_static
(locked_exclusive
=> 0);
214 ###########################################
215 # exclusive shared lock
217 elsif ($self -> locked_exsh
) {
218 # try to decrease the reference counter
220 if ($self -> es_sub_ref
($timeout)) {
221 $self -> remove_exsh_announce
;
222 $self -> set_static
(locked_exsh
=> 0);
228 ###########################################
237 $self -> unlock_violent
;
241 ### sub unlock_violent #########################################################
243 # remove any lock violently (excludes master lock)
247 # Return: -none- (the success is undefined)
252 unless ($self -> masterlocked
) {
254 # find out last modification time
255 # and do nothing unless 'violent-timout' is over
257 my $time = $self -> _reftime
;
260 return if ((time - $time) < $self -> timeout
('violent'));
263 $self -> set_ref
(0); # reference counter = 0
264 $self -> _simple_unlock
($self -> reflock
); # release reference counter file
265 $self -> _simple_unlock
($self -> exshlock
); # remove excl shared lock
266 $self -> _simple_unlock
($self -> lockfile
); # release file
272 ### sub release ################################################################
283 $self -> set_ref
(0); # reference counter = 0
284 $self -> _simple_unlock
($self -> reflock
); # release reference counter
285 $self -> _simple_unlock
($self -> lockfile
); # remove any write lock announce
286 $self -> _simple_unlock
($self -> exshlock
); # remove any excl shared lock
287 $self -> _simple_unlock
($self -> masterlock
); # remove master lock
292 # keep 'require' happy
297 ### end of Lock::API ###########################################################
patrick-canterino.de