-  my $filename=shift;
-  my ($timeout)=(shift (@_) or $Timeout);
-
-  unless (-l &masterlockfile($filename) and not $iAmMaster) {
-    # bevorstehenden Schreibzugriff anmelden
-    &simple_lock ($filename,$timeout) or return 0;
-
-    my $i;
-    for ($i=0 ; $i<=$timeout ; $i++) {
-      # Referenzdatei sperren
-      &simple_lock (&reffile($filename),$timeout) or (return &simple_unlock($filename,$timeout) and 0);
-
-      # Referenzzaehler = 0 ? => okay
-      return 1 if (&get_ref ($filename) == 0);
-
-      # Referenzdatei wieder freigeben
-      &simple_unlock (&reffile($filename),$timeout) or (return &simple_unlock($filename,$timeout) and 0);
-      sleep(1);}
-
-    &simple_unlock ($filename);}
+  my $filename = shift;
+  my $timeout  = shift || $Timeout;
+  my $rest = ($LOCKED{$filename} and $LOCKED{$filename} == 1) ? 1 : 0;
+
+  unless (-l masterlockfile($filename) and not $iAmMaster) {
+    # announce the write lock
+    # and wait $timeout seconds for
+    # references == 0 (no shared locks set)
+    #
+    simple_lock ($filename,$timeout) or return 0;
+    for (1..$timeout) {
+
+      # lock reference counter
+      # or fail
+      #
+      unless (simple_lock (&reffile($filename),$timeout)) {
+        simple_unlock($filename,$timeout);
+        return 0;
+      }
+
+      # ready if we have no shared locks
+      #
+      if (get_ref ($filename) == $rest) {
+        $LOCKED{$filename} = 2 | ($rest ? 1 : 0);
+        return 1;
+      };
+
+      # release reference counter
+      # shared locks get the chance to be removed
+      #
+      unless (simple_unlock (&reffile($filename),$timeout)) {
+        simple_unlock($filename,$timeout);
+        return 0;
+      }
+      sleep(1);
+    }
+
+    # write lock failed
+    # remove the announcement
+    #
+    simple_unlock ($filename);
+  }