[git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-104-g567a31c

by Werner Koch cvs at cvs.gnupg.org
Wed Sep 28 12:33:19 CEST 2011


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  567a31c2a0c6d5cbf700b4667e1bb91389fd2246 (commit)
      from  8a033fecfb4c73b8f7d1119272c10e64d9176bcb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 567a31c2a0c6d5cbf700b4667e1bb91389fd2246
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Sep 28 11:47:40 2011 +0200

    Allow arbitrary timeouts with dotlock.

diff --git a/common/ChangeLog b/common/ChangeLog
index e0fc2dd..0f66a41 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,8 @@
+2011-09-28  Werner Koch  <wk at g10code.com>
+
+	* dotlock.c (dotlock_take, dotlock_take_unix, dotlock_take_w32):
+	Implement arbitrary timeout values.
+
 2011-09-27  Werner Koch  <wk at g10code.com>
 
 	* dotlock.c (dotlock_take_unix): Check only the link count and not
diff --git a/common/dotlock.c b/common/dotlock.c
index 97a3f74..e3e9fa3 100644
--- a/common/dotlock.c
+++ b/common/dotlock.c
@@ -87,8 +87,10 @@
 
    This function will wait until the lock is acquired.  If an
    unexpected error occurs if will return non-zero and set ERRNO.  If
-   you pass (0) instead of (-1) the function does not wait if the file
-   is already locked but returns -1 and sets ERRNO to EACCES.
+   you pass (0) instead of (-1) the function does not wait in case the
+   file is already locked but returns -1 and sets ERRNO to EACCES.
+   Any other positive value for the second parameter is considered a
+   timeout valuie in milliseconds.
 
    To release the lock you call:
 
@@ -805,15 +807,20 @@ dotlock_destroy (dotlock_t h)
 
 
 #ifdef HAVE_POSIX_SYSTEM
-/* Unix specific code of make_dotlock.  Returns 0 on success, -1 on
-   error and 1 to try again.  */
+/* Unix specific code of make_dotlock.  Returns 0 on success and -1 on
+   error.  */
 static int
-dotlock_take_unix (dotlock_t h, long timeout, int *backoff)
+dotlock_take_unix (dotlock_t h, long timeout)
 {
-  int  pid;
+  int wtime = 0;
+  int sumtime = 0;
+  int pid;
+  int lastpid = -1;
+  int ownerchanged;
   const char *maybe_dead="";
   int same_node;
 
+ again:
   if (h->use_o_excl)
     {
       /* No hardlink support - use open(O_EXCL).  */
@@ -889,7 +896,7 @@ dotlock_take_unix (dotlock_t h, long timeout, int *backoff)
           return -1;
         }
       my_info_0 ("lockfile disappeared\n");
-      return 1; /* Try again.  */
+      goto again;
     }
   else if ( pid == getpid() && same_node )
     {
@@ -904,24 +911,49 @@ dotlock_take_unix (dotlock_t h, long timeout, int *backoff)
          of the stale file tries to lock right at the same time as we.  */
       my_info_1 (_("removing stale lockfile (created by %d)\n"), pid);
       unlink (h->lockname);
-      return 1; /* Try again.  */
+      goto again;
     }
 
-  if ( timeout == -1 )
+  if (lastpid == -1)
+    lastpid = pid;
+  ownerchanged = (pid != lastpid);
+
+  if (timeout)
     {
-      /* Wait until lock has been released. */
       struct timeval tv;
 
-      my_info_3 (_("waiting for lock (held by %d%s) %s...\n"),
-                 pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
+      /* Wait until lock has been released.  We use increasing retry
+         intervals of 50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s
+         but reset it if the lock owner meanwhile changed.  */
+      if (!wtime || ownerchanged)
+        wtime = 50;
+      else if (wtime < 800)
+        wtime *= 2;
+      else if (wtime == 800)
+        wtime = 2000;
+      else if (wtime < 8000)
+        wtime *= 2;
+
+      if (timeout > 0)
+        {
+          if (wtime > timeout)
+            wtime = timeout;
+          timeout -= wtime;
+        }
+
+      sumtime += wtime;
+      if (sumtime >= 1500)
+        {
+          sumtime = 0;
+          my_info_3 (_("waiting for lock (held by %d%s) %s...\n"),
+                     pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
+        }
+
 
-      /* We can't use sleep, cause signals may be blocked. */
-      tv.tv_sec = 1 + *backoff;
-      tv.tv_usec = 0;
+      tv.tv_sec = wtime / 1000;
+      tv.tv_usec = (wtime % 1000) * 1000;
       select (0, NULL, NULL, NULL, &tv);
-      if ( *backoff < 10 )
-        ++*backoff;
-      return 1; /* Try again.  */
+      goto again;
     }
 
   jnlib_set_errno (EACCES);
@@ -931,14 +963,16 @@ dotlock_take_unix (dotlock_t h, long timeout, int *backoff)
 
 
 #ifdef HAVE_DOSISH_SYSTEM
-/* Windows specific code of make_dotlock.  Returns 0 on success, -1 on
-   error and 1 to try again.  */
+/* Windows specific code of make_dotlock.  Returns 0 on success and -1 on
+   error.  */
 static int
-dotlock_take_w32 (dotlock_t h, long timeout, int *backoff)
+dotlock_take_w32 (dotlock_t h, long timeout)
 {
+  int wtime = 0;
   int w32err;
   OVERLAPPED ovl;
 
+ again:
   /* Lock one byte at offset 0.  The offset is given by OVL.  */
   memset (&ovl, 0, sizeof ovl);
   if (LockFileEx (h->lockhd, (LOCKFILE_EXCLUSIVE_LOCK
@@ -956,14 +990,31 @@ dotlock_take_w32 (dotlock_t h, long timeout, int *backoff)
       return -1;
     }
 
-  if ( timeout == -1 )
+  if (timeout)
     {
-      /* Wait until lock has been released. */
-      my_info_1 (_("waiting for lock %s...\n"), h->lockname);
-      Sleep ((1 + *backoff)*1000);
-      if ( *backoff < 10 )
-        ++*backoff;
-      return 1; /* Try again.  */
+      /* Wait until lock has been released.  We use retry intervals of
+         50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s.  */
+      if (!wtime)
+        wtime = 50;
+      else if (wtime < 800)
+        wtime *= 2;
+      else if (wtime == 800)
+        wtime = 2000;
+      else if (wtime < 8000)
+        wtime *= 2;
+
+      if (timeout > 0)
+        {
+          if (wtime > timeout)
+            wtime = timeout;
+          timeout -= wtime;
+        }
+
+      if (wtime >= 800)
+        my_info_1 (_("waiting for lock %s...\n"), h->lockname);
+
+      Sleep (wtime);
+      goto again;
     }
 
   return -1;
@@ -973,12 +1024,10 @@ dotlock_take_w32 (dotlock_t h, long timeout, int *backoff)
 
 /* Take a lock on H.  A value of 0 for TIMEOUT returns immediately if
    the lock can't be taked, -1 waits forever (hopefully not), other
-   values are reserved (planned to be timeouts in milliseconds).
-   Returns: 0 on success  */
+   values wait for TIMEOUT milliseconds.  Returns: 0 on success  */
 int
 dotlock_take (dotlock_t h, long timeout)
 {
-  int backoff = 0;
   int ret;
 
   if ( h->disable )
@@ -990,15 +1039,11 @@ dotlock_take (dotlock_t h, long timeout)
       return 0;
     }
 
-  do
-    {
 #ifdef HAVE_DOSISH_SYSTEM
-      ret = dotlock_take_w32 (h, timeout, &backoff);
+  ret = dotlock_take_w32 (h, timeout);
 #else /*!HAVE_DOSISH_SYSTEM*/
-      ret = dotlock_take_unix (h, timeout, &backoff);
+  ret = dotlock_take_unix (h, timeout);
 #endif /*!HAVE_DOSISH_SYSTEM*/
-    }
-  while (ret == 1);
 
   return ret;
 }

-----------------------------------------------------------------------

Summary of changes:
 common/ChangeLog |    5 ++
 common/dotlock.c |  119 +++++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 87 insertions(+), 37 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list