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*