]> git.p6c8.net - selfforum.git/blobdiff - selfforum-cgi/shared/Lock/_simple.pm
added submodules of new Lock.pm
[selfforum.git] / selfforum-cgi / shared / Lock / _simple.pm
diff --git a/selfforum-cgi/shared/Lock/_simple.pm b/selfforum-cgi/shared/Lock/_simple.pm
new file mode 100644 (file)
index 0000000..7aae43a
--- /dev/null
@@ -0,0 +1,351 @@
+package Lock::_simple;
+
+################################################################################
+#                                                                              #
+# File:        shared/Lock/_simple.pm                                          #
+#                                                                              #
+# Authors:     Andre Malo       <nd@o3media.de>, 2001-05-25                    #
+#                                                                              #
+# Description: belongs to Locking and Filehandle class                         #
+#              NOT FOR PUBLIC USE                                              #
+#                                                                              #
+################################################################################
+
+use strict;
+use vars qw(
+  $VERSION
+);
+
+use Fcntl;
+
+################################################################################
+#
+# Version check
+#
+$VERSION = do { my @r =(q$Revision$ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };
+
+### sub _simple_esna ###########################################################
+#
+# simple file lock
+# excl shared lock announced, no locking possible
+#
+# Params: $filename - filename
+#         $timeout  - timeout
+#
+# Return: success code (boolean)
+#
+sub _simple_esna {
+  my ($self, $filename, $timeout) = @_;
+  my $fh = new Lock::Handle ($filename);
+
+  for (0..$timeout) {
+    unless ($self -> exsh_announced) {
+      $self -> _simple_lock ($fh) and return 1;
+    }
+    sleep 1;
+  }
+
+  # timeout
+  return;
+}
+
+### sub _simple_ana ############################################################
+#
+# simple file lock
+# while excl lock announced, no locking possible
+#
+# Params: $filename - filename
+#         $timeout  - timeout
+#
+# Return: success code (boolean)
+#
+sub _simple_ana {
+  my ($self, $filename, $timeout) = @_;
+  my $fh = new Lock::Handle ($filename);
+
+  for (0..$timeout) {
+    unless ($self -> excl_announced) {
+      $self -> _simple_lock ($fh) and return 1;
+    }
+    sleep 1;
+  }
+
+  # timeout
+  return;
+}
+
+### sub _simple_aa #############################################################
+#
+# simple file lock
+# while excl lock announced, locking is possible
+#
+# Params: $filename - filename
+#         $timeout  - timeout
+#
+# Return: success code (boolean)
+#
+sub _simple_aa {
+  my ($self, $filename, $timeout) = @_;
+  my $fh = new Lock::Handle ($filename);
+
+  for (0..$timeout) {
+    $self -> _simple_lock ($fh) and return 1;
+    sleep 1;
+  }
+
+  # timeout
+  return;
+}
+
+### sub es_add_ref #############################################################
+#
+# increase shared lock reference counter
+# (for excl shared lock)
+#
+# Params: $timeout - timeout
+#
+# Return: success code (boolean)
+#
+sub es_add_ref {
+  my ($self, $timeout) = @_;
+
+  # lock reference counter file
+  # increase reference counter
+  # set excl shared lock
+  # release ref. counter file
+  #
+  return unless($self -> _simple_esna ($self->reflock, $timeout));
+  $self -> set_ref ($self -> get_ref + 1)                       or return;
+  $self -> set_exsh_announce                                    or return;
+  $self -> _simple_unlock ($self -> reflock)                    or return;
+
+  # successfully done
+  1;
+}
+
+### sub es_sub_ref #############################################################
+#
+# decrease shared lock reference counter
+# (of an excl shared locked file)
+#
+# Params: $timeout - timeout
+#
+# Return: success code (boolean)
+#
+sub es_sub_ref {
+  my ($self, $timeout) = @_;
+
+  # lock reference counter file
+  # increase reference counter
+  # release ref. counter file
+  #
+  return unless($self -> _simple_aa ($self->reflock, $timeout));
+  $self -> set_ref ($self -> get_ref - 1)                       or return;
+  $self -> remove_exsh_announce;
+  $self -> _simple_unlock ($self -> reflock)                    or return;
+
+  # successfully done
+  1;
+}
+
+### sub add_ref ################################################################
+#
+# increase shared lock reference counter
+#
+# Params: $timeout - timeout
+#
+# Return: success code (boolean)
+#
+sub add_ref {
+  my ($self, $timeout) = @_;
+
+  # lock reference counter file
+  # increase reference counter
+  # release ref. counter file
+  #
+  return unless($self -> _simple_ana ($self->reflock, $timeout));
+  $self -> set_ref ($self -> get_ref + 1)                       or return;
+  $self -> _simple_unlock ($self -> reflock)                    or return;
+
+  # successfully done
+  1;
+}
+
+### sub sub_ref ################################################################
+#
+# decrease shared lock reference counter
+#
+# Params: $timeout - timeout
+#
+# Return: success code (boolean)
+#
+sub sub_ref {
+  my ($self, $timeout) = @_;
+
+  # lock reference counter file
+  # increase reference counter
+  # release ref. counter file
+  #
+  return unless($self -> _simple_aa ($self->reflock, $timeout));
+  $self -> set_ref ($self -> get_ref - 1)                       or return;
+  $self -> _simple_unlock ($self -> reflock)                    or return;
+
+  # successfully done
+  1;
+}
+
+### sub get_ref ################################################################
+#
+# read out the reference counter
+# NO LOCKING HERE!
+#
+# Params: ~none~
+#
+# Return: counter value
+#
+sub get_ref {
+  my $self = shift;
+  my ($fh, $val) = new Lock::Handle ($self -> reffile);
+
+  {
+    local $/;
+    sysopen ($fh, $fh->filename, O_RDONLY)                      or return 0;
+    $val = <$fh>;
+    close $fh;
+  }
+
+  # return value
+  #
+  $val;
+}
+
+### sub set_ref ################################################################
+#
+# write reference counter into file
+# NO LOCKING HERE!
+#
+# Params: counter value
+#
+# Return: success code (boolean)
+#
+sub set_ref {
+  my ($self, $val) = @_;
+  my $fh = new Lock::Handle ($self -> reffile);
+
+  if ($val == 0) {
+    if (-f $fh->filename) {
+      unlink $fh->filename                                      or return;
+    }
+  }
+  else {
+    local $\;
+    sysopen ($fh, $fh->filename, O_WRONLY | O_TRUNC | O_CREAT)  or return;
+    print $fh $val                                              or do {
+                                                                  close $fh;
+                                                                  unlink $fh->filename;
+                                                                  return;
+                                                                };
+
+    close $fh                                                   or do {
+                                                                  unlink $fh->filename;
+                                                                  return;
+                                                                };
+  }
+
+  # successfully done
+  #
+  1;
+}
+
+### sub set_excl_announce ######################################################
+#
+# try to announce an exclusive lock
+#
+# Params: ~none~
+#
+# Return: status (boolean)
+#
+sub set_excl_announce {
+  my $self = shift;
+
+  if ($self -> excl_announced) {
+    return ($self -> announced) ? 1 : return;
+  }
+
+  if ($self -> _simple_lock (new Lock::Handle ($self -> lockfile))) {
+    $self -> set_static (announced => 1);
+    return 1;
+  }
+
+  return;
+}
+
+### sub remove_excl_announce ###################################################
+#
+# remove announce of an exclusive lock, if it's set by ourself
+#
+# Params: ~none~
+#
+# Return: ~none~
+#
+sub remove_excl_announce {
+  my $self = shift;
+
+  if ($self -> excl_announced and $self -> announced) {
+    $self -> _simple_unlock ($self -> lockfile);
+  }
+
+  $self -> set_static (announced => 0);
+
+  return;
+}
+
+### sub set_exsh_announce ######################################################
+#
+# try to announce an exclusive shared lock
+#
+# Params: ~none~
+#
+# Return: status (boolean)
+#
+sub set_exsh_announce {
+  my $self = shift;
+
+  if ($self -> exsh_announced) {
+    return ($self -> es_announced) ? 1 : return;
+  }
+
+  if ($self -> _simple_lock (new Lock::Handle ($self -> exshlock))) {
+    $self -> set_static (es_announced => 1);
+    return 1;
+  }
+
+  return;
+}
+
+### sub remove_exsh_announce ###################################################
+#
+# remove an exclusive shared lock, if it's set by ourself
+#
+# Params: ~none~
+#
+# Return: ~none~
+#
+sub remove_exsh_announce {
+  my $self = shift;
+
+  if ($self -> exsh_announced and $self -> es_announced) {
+    $self -> _simple_unlock ($self -> exshlock);
+  }
+
+  $self -> set_static (es_announced => 0);
+
+  return;
+}
+
+# keep 'require' happy
+1;
+
+#
+#
+### end of Lock::_simple #######################################################
\ No newline at end of file

patrick-canterino.de