]> git.p6c8.net - selfforum.git/blob - selfforum-cgi/shared/Lock/_simple.pm
improved the behavior of get_all_threads and create_forum_xml_string
[selfforum.git] / selfforum-cgi / shared / Lock / _simple.pm
1 package Lock::_simple;
2
3 ################################################################################
4 # #
5 # File: shared/Lock/_simple.pm #
6 # #
7 # Authors: André Malo <nd@o3media.de> #
8 # #
9 # Description: belongs to Locking and Filehandle class #
10 # NOT FOR PUBLIC USE #
11 # #
12 ################################################################################
13
14 use strict;
15 use Fcntl;
16
17 ################################################################################
18 #
19 # Version check
20 #
21 # last modified:
22 # $Date$ (GMT)
23 # by $Author$
24 #
25 sub VERSION {(q$Revision$ =~ /([\d.]+)\s*$/)[0] or '0.0'}
26
27 ### sub _simple_esna ###########################################################
28 #
29 # simple file lock
30 # excl shared lock announced, no locking possible
31 #
32 # Params: $filename - filename
33 # $timeout - timeout
34 #
35 # Return: success code (boolean)
36 #
37 sub _simple_esna {
38 my ($self, $filename, $timeout) = @_;
39 my $fh = new Lock::Handle ($filename);
40
41 for (0..$timeout) {
42 unless ($self -> exsh_announced) {
43 $self -> _simple_lock ($fh) and return 1;
44 }
45 sleep 1;
46 }
47
48 # timeout
49 return;
50 }
51
52 ### sub _simple_ana ############################################################
53 #
54 # simple file lock
55 # while excl lock announced, no locking possible
56 #
57 # Params: $filename - filename
58 # $timeout - timeout
59 #
60 # Return: success code (boolean)
61 #
62 sub _simple_ana {
63 my ($self, $filename, $timeout) = @_;
64 my $fh = new Lock::Handle ($filename);
65
66 for (0..$timeout) {
67 unless ($self -> excl_announced) {
68 $self -> _simple_lock ($fh) and return 1;
69 }
70 sleep 1;
71 }
72
73 # timeout
74 return;
75 }
76
77 ### sub _simple_aa #############################################################
78 #
79 # simple file lock
80 # while excl lock announced, locking is possible
81 #
82 # Params: $filename - filename
83 # $timeout - timeout
84 #
85 # Return: success code (boolean)
86 #
87 sub _simple_aa {
88 my ($self, $filename, $timeout) = @_;
89 my $fh = new Lock::Handle ($filename);
90
91 for (0..$timeout) {
92 $self -> _simple_lock ($fh) and return 1;
93 sleep 1;
94 }
95
96 # timeout
97 return;
98 }
99
100 ### sub es_add_ref #############################################################
101 #
102 # increase shared lock reference counter
103 # (for excl shared lock)
104 #
105 # Params: $timeout - timeout
106 #
107 # Return: success code (boolean)
108 #
109 sub es_add_ref {
110 my ($self, $timeout) = @_;
111
112 # lock reference counter file
113 # increase reference counter
114 # set excl shared lock
115 # release ref. counter file
116 #
117 return unless($self -> _simple_esna ($self->reflock, $timeout));
118 $self -> set_ref ($self -> get_ref + 1) or return;
119 $self -> set_exsh_announce or return;
120 $self -> _simple_unlock ($self -> reflock) or return;
121
122 # successfully done
123 1;
124 }
125
126 ### sub es_sub_ref #############################################################
127 #
128 # decrease shared lock reference counter
129 # (of an excl shared locked file)
130 #
131 # Params: $timeout - timeout
132 #
133 # Return: success code (boolean)
134 #
135 sub es_sub_ref {
136 my ($self, $timeout) = @_;
137
138 # lock reference counter file
139 # increase reference counter
140 # release ref. counter file
141 #
142 return unless($self -> _simple_aa ($self->reflock, $timeout));
143 $self -> set_ref ($self -> get_ref - 1) or return;
144 $self -> remove_exsh_announce;
145 $self -> _simple_unlock ($self -> reflock) or return;
146
147 # successfully done
148 1;
149 }
150
151 ### sub add_ref ################################################################
152 #
153 # increase shared lock reference counter
154 #
155 # Params: $timeout - timeout
156 #
157 # Return: success code (boolean)
158 #
159 sub add_ref {
160 my ($self, $timeout) = @_;
161
162 # lock reference counter file
163 # increase reference counter
164 # release ref. counter file
165 #
166 return unless($self -> _simple_ana ($self->reflock, $timeout));
167 $self -> set_ref ($self -> get_ref + 1) or return;
168 $self -> _simple_unlock ($self -> reflock) or return;
169
170 # successfully done
171 1;
172 }
173
174 ### sub sub_ref ################################################################
175 #
176 # decrease shared lock reference counter
177 #
178 # Params: $timeout - timeout
179 #
180 # Return: success code (boolean)
181 #
182 sub sub_ref {
183 my ($self, $timeout) = @_;
184
185 # lock reference counter file
186 # increase reference counter
187 # release ref. counter file
188 #
189 return unless($self -> _simple_aa ($self->reflock, $timeout));
190 $self -> set_ref ($self -> get_ref - 1) or return;
191 $self -> _simple_unlock ($self -> reflock) or return;
192
193 # successfully done
194 1;
195 }
196
197 ### sub get_ref ################################################################
198 #
199 # read out the reference counter
200 # NO LOCKING HERE!
201 #
202 # Params: ~none~
203 #
204 # Return: counter value
205 #
206 sub get_ref {
207 my $self = shift;
208 my ($fh, $val) = new Lock::Handle ($self -> reffile);
209
210 {
211 local $/;
212 sysopen ($fh, $fh->filename, O_RDONLY) or return 0;
213 $val = <$fh>;
214 close $fh;
215 }
216
217 # return value
218 #
219 $val;
220 }
221
222 ### sub set_ref ################################################################
223 #
224 # write reference counter into file
225 # NO LOCKING HERE!
226 #
227 # Params: counter value
228 #
229 # Return: success code (boolean)
230 #
231 sub set_ref {
232 my ($self, $val) = @_;
233 my $fh = new Lock::Handle ($self -> reffile);
234
235 if ($val == 0) {
236 if (-f $fh->filename) {
237 unlink $fh->filename or return;
238 }
239 }
240 else {
241 local $\;
242 sysopen ($fh, $fh->filename, O_WRONLY | O_TRUNC | O_CREAT) or return;
243 print $fh $val or do {
244 close $fh;
245 unlink $fh->filename;
246 return;
247 };
248
249 close $fh or do {
250 unlink $fh->filename;
251 return;
252 };
253 }
254
255 # successfully done
256 #
257 1;
258 }
259
260 ### sub set_excl_announce ######################################################
261 #
262 # try to announce an exclusive lock
263 #
264 # Params: ~none~
265 #
266 # Return: status (boolean)
267 #
268 sub set_excl_announce {
269 my $self = shift;
270
271 if ($self -> excl_announced) {
272 return ($self -> announced) ? 1 : return;
273 }
274
275 if ($self -> _simple_lock (new Lock::Handle ($self -> lockfile))) {
276 $self -> set_static (announced => 1);
277 return 1;
278 }
279
280 return;
281 }
282
283 ### sub remove_excl_announce ###################################################
284 #
285 # remove announce of an exclusive lock, if it's set by ourself
286 #
287 # Params: ~none~
288 #
289 # Return: ~none~
290 #
291 sub remove_excl_announce {
292 my $self = shift;
293
294 if ($self -> excl_announced and $self -> announced) {
295 $self -> _simple_unlock ($self -> lockfile);
296 }
297
298 $self -> set_static (announced => 0);
299
300 return;
301 }
302
303 ### sub set_exsh_announce ######################################################
304 #
305 # try to announce an exclusive shared lock
306 #
307 # Params: ~none~
308 #
309 # Return: status (boolean)
310 #
311 sub set_exsh_announce {
312 my $self = shift;
313
314 if ($self -> exsh_announced) {
315 return ($self -> es_announced) ? 1 : return;
316 }
317
318 if ($self -> _simple_lock (new Lock::Handle ($self -> exshlock))) {
319 $self -> set_static (es_announced => 1);
320 return 1;
321 }
322
323 return;
324 }
325
326 ### sub remove_exsh_announce ###################################################
327 #
328 # remove an exclusive shared lock, if it's set by ourself
329 #
330 # Params: ~none~
331 #
332 # Return: ~none~
333 #
334 sub remove_exsh_announce {
335 my $self = shift;
336
337 if ($self -> exsh_announced and $self -> es_announced) {
338 $self -> _simple_unlock ($self -> exshlock);
339 }
340
341 $self -> set_static (es_announced => 0);
342
343 return;
344 }
345
346 # keep 'require' happy
347 1;
348
349 #
350 #
351 ### end of Lock::_simple #######################################################

patrick-canterino.de