You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2017/04/16 10:28:40 UTC

[02/16] lucy git commit: Don't allow double obtain/release

Don't allow double obtain/release


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/79161a4b
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/79161a4b
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/79161a4b

Branch: refs/heads/master
Commit: 79161a4b233ce3570ecf4c48745b469ccb50aec7
Parents: 3e22986
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Feb 17 13:53:59 2017 +0100
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Mon Feb 20 16:26:21 2017 +0100

----------------------------------------------------------------------
 core/Lucy/Store/Lock.c   | 51 ++++++++++++++++++++++++++++---------------
 core/Lucy/Store/Lock.cfh |  1 +
 2 files changed, 34 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/79161a4b/core/Lucy/Store/Lock.c
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/Lock.c b/core/Lucy/Store/Lock.c
index 6d39362..d187405 100644
--- a/core/Lucy/Store/Lock.c
+++ b/core/Lucy/Store/Lock.c
@@ -123,6 +123,10 @@ Lock_Obtain_Exclusive_IMP(Lock *self) {
 
 /***************************************************************************/
 
+#define LFLOCK_STATE_UNLOCKED          0
+#define LFLOCK_STATE_LOCKED_SHARED     1
+#define LFLOCK_STATE_LOCKED_EXCLUSIVE  2
+
 static bool
 S_request(LockFileLockIVARS *ivars, String *lock_path);
 
@@ -182,6 +186,10 @@ LFLock_Request_Shared_IMP(LockFileLock *self) {
         THROW(ERR, "Can't request shared lock if exclusive_only is set");
     }
 
+    if (ivars->state != LFLOCK_STATE_UNLOCKED) {
+        THROW(ERR, "Lock already acquired");
+    }
+
     // TODO: The is_locked test and subsequent file creation is prone to a
     // race condition. We could protect the whole process with an internal
     // exclusive lock.
@@ -192,16 +200,7 @@ LFLock_Request_Shared_IMP(LockFileLock *self) {
         return false;
     }
 
-    String *path = ivars->shared_lock_path;
-
-    // Null shared_lock_path indicates whether this particular instance is
-    // locked.
-    if (path && Folder_Exists(ivars->folder, path)) {
-        // Don't allow double obtain.
-        String *msg = Str_newf("Lock already obtained via '%o'", path);
-        Err_set_error((Err*)LockErr_new(msg));
-        return false;
-    }
+    String *path = NULL;
 
     uint32_t i = 0;
     do {
@@ -211,11 +210,11 @@ LFLock_Request_Shared_IMP(LockFileLock *self) {
 
     if (S_request(ivars, path)) {
         ivars->shared_lock_path = path;
+        ivars->state = LFLOCK_STATE_LOCKED_SHARED;
         return true;
     }
     else {
         DECREF(path);
-        ivars->shared_lock_path = NULL;
         return false;
     }
 }
@@ -224,6 +223,10 @@ bool
 LFLock_Request_Exclusive_IMP(LockFileLock *self) {
     LockFileLockIVARS *const ivars = LFLock_IVARS(self);
 
+    if (ivars->state != LFLOCK_STATE_UNLOCKED) {
+        THROW(ERR, "Lock already acquired");
+    }
+
     // TODO: The is_locked test and subsequent file creation is prone to a
     // race condition. We could protect the whole process with an internal
     // exclusive lock.
@@ -237,7 +240,13 @@ LFLock_Request_Exclusive_IMP(LockFileLock *self) {
         return false;
     }
 
-    return S_request(ivars, ivars->lock_path);
+    if (S_request(ivars, ivars->lock_path)) {
+        ivars->state = LFLOCK_STATE_LOCKED_EXCLUSIVE;
+        return true;
+    }
+    else {
+        return false;
+    }
 }
 
 static bool
@@ -321,7 +330,16 @@ void
 LFLock_Release_IMP(LockFileLock *self) {
     LockFileLockIVARS *const ivars = LFLock_IVARS(self);
 
-    if (ivars->shared_lock_path) {
+    if (ivars->state == LFLOCK_STATE_UNLOCKED) {
+        THROW(ERR, "Lock not acquired");
+    }
+
+    if (ivars->state == LFLOCK_STATE_LOCKED_EXCLUSIVE) {
+        if (Folder_Exists(ivars->folder, ivars->lock_path)) {
+            S_maybe_delete_file(ivars, ivars->lock_path, true, false);
+        }
+    }
+    else { // Shared lock.
         if (Folder_Exists(ivars->folder, ivars->shared_lock_path)) {
             S_maybe_delete_file(ivars, ivars->shared_lock_path, true, false);
         }
@@ -330,11 +348,8 @@ LFLock_Release_IMP(LockFileLock *self) {
         DECREF(ivars->shared_lock_path);
         ivars->shared_lock_path = NULL;
     }
-    else {
-        if (Folder_Exists(ivars->folder, ivars->lock_path)) {
-            S_maybe_delete_file(ivars, ivars->lock_path, true, false);
-        }
-    }
+
+    ivars->state = LFLOCK_STATE_UNLOCKED;
 }
 
 bool

http://git-wip-us.apache.org/repos/asf/lucy/blob/79161a4b/core/Lucy/Store/Lock.cfh
----------------------------------------------------------------------
diff --git a/core/Lucy/Store/Lock.cfh b/core/Lucy/Store/Lock.cfh
index bef6dae..fb813e1 100644
--- a/core/Lucy/Store/Lock.cfh
+++ b/core/Lucy/Store/Lock.cfh
@@ -127,6 +127,7 @@ class Lucy::Store::LockFileLock nickname LFLock
 
     String *shared_lock_path;
     String *link_path;
+    int     state;
     bool    exclusive_only;
 
     inert incremented LockFileLock*