s3: Avoid starving locks when many processes die at the same time
authorVolker Lendecke <vl@samba.org>
Tue, 16 Feb 2010 11:28:53 +0000 (12:28 +0100)
committerVolker Lendecke <vl@samba.org>
Tue, 16 Feb 2010 15:39:50 +0000 (16:39 +0100)
In g_lock_unlock we have a little race between the process_exists and
messaging_send call: We only send to 5 waiters now, they all might have died
between us checking their existence and sending the message. This change makes
g_lock_lock retry at least once every minute.

source3/lib/g_lock.c

index 1b4caaf0aad221c0482fae1fb9a2cf0aa9b8d5cd..54441643278e2e6b5bd4d69ec09b5c6ce31282b3 100644 (file)
@@ -302,7 +302,6 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, const char *name,
        NTSTATUS status;
        bool retry = false;
        struct timeval timeout_end;
-       struct timeval timeout_remaining;
        struct timeval time_now;
 
        DEBUG(10, ("Trying to acquire lock %d for %s\n", (int)lock_type,
@@ -341,6 +340,7 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, const char *name,
                fd_set *r_fds = NULL;
                int max_fd = 0;
                int ret;
+               struct timeval select_timeout;
 
                status = g_lock_trylock(ctx, name, lock_type);
                if (NT_STATUS_IS_OK(status)) {
@@ -397,12 +397,10 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, const char *name,
                }
 #endif
 
-               time_now = timeval_current();
-               timeout_remaining = timeval_until(&time_now, &timeout_end);
+               select_timeout = timeval_set(60, 0);
 
                ret = sys_select(max_fd + 1, r_fds, NULL, NULL,
-                                &timeout_remaining);
-
+                                &select_timeout);
                if (ret == -1) {
                        if (errno != EINTR) {
                                DEBUG(1, ("error calling select: %s\n",
@@ -423,7 +421,7 @@ NTSTATUS g_lock_lock(struct g_lock_ctx *ctx, const char *name,
                                break;
                        } else {
                                DEBUG(10, ("select returned 0 but timeout not "
-                                          "not expired: strange - retrying\n"));
+                                          "not expired, retrying\n"));
                        }
                } else if (ret != 1) {
                        DEBUG(1, ("invalid return code of select: %d\n", ret));