summaryrefslogtreecommitdiffstats
path: root/ctdb/server/ctdb_lock.c
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2013-08-02 10:54:38 +1000
committerAmitay Isaacs <amitay@gmail.com>2013-08-09 11:04:55 +1000
commit477a51aba5e36324263614cad6bef5d4c4c98942 (patch)
tree31a4726fe8409a89f7089c8c0d89c2fbfb29f581 /ctdb/server/ctdb_lock.c
parent9ba793a80ff489ba5ec40b3a55bef5f97aac634e (diff)
downloadsamba-477a51aba5e36324263614cad6bef5d4c4c98942.tar.gz
samba-477a51aba5e36324263614cad6bef5d4c4c98942.tar.xz
samba-477a51aba5e36324263614cad6bef5d4c4c98942.zip
locking: Do not create multiple lock processes for the same key
If there are multiple lock helper processes waiting for the same record, then it will cause a thundering herd when that record has been unlocked. So avoid scheduling lock contexts for the same record. This will also mean that multiple requests will get queued up behind the same lock context and can be processed quickly once the lock has been obtained. Signed-off-by: Amitay Isaacs <amitay@gmail.com> (This used to be ctdb commit ebecc3a18f1cb397a78b56eaf8f752dd5495bcc9)
Diffstat (limited to 'ctdb/server/ctdb_lock.c')
-rw-r--r--ctdb/server/ctdb_lock.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/ctdb/server/ctdb_lock.c b/ctdb/server/ctdb_lock.c
index b313ed57358..1d27a444b66 100644
--- a/ctdb/server/ctdb_lock.c
+++ b/ctdb/server/ctdb_lock.c
@@ -707,7 +707,7 @@ done:
*/
static void ctdb_lock_schedule(struct ctdb_context *ctdb)
{
- struct lock_context *lock_ctx, *next_ctx;
+ struct lock_context *lock_ctx, *next_ctx, *active_ctx;
int ret;
TALLOC_CTX *tmp_ctx;
const char *helper = BINDIR "/ctdb_lock_helper";
@@ -737,8 +737,8 @@ static void ctdb_lock_schedule(struct ctdb_context *ctdb)
/* Find a lock context with requests */
lock_ctx = ctdb->lock_pending;
while (lock_ctx != NULL) {
+ next_ctx = lock_ctx->next;
if (! lock_ctx->req_queue) {
- next_ctx = lock_ctx->next;
DEBUG(DEBUG_INFO, ("Removing lock context without lock requests\n"));
DLIST_REMOVE(ctdb->lock_pending, lock_ctx);
ctdb->lock_num_pending--;
@@ -747,12 +747,21 @@ static void ctdb_lock_schedule(struct ctdb_context *ctdb)
CTDB_DECREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_pending);
}
talloc_free(lock_ctx);
- lock_ctx = next_ctx;
- continue;
} else {
- /* Found a lock context with lock requests */
- break;
+ active_ctx = find_lock_context(ctdb->lock_current, lock_ctx->ctdb_db,
+ lock_ctx->key, lock_ctx->priority,
+ lock_ctx->type);
+ if (active_ctx == NULL) {
+ /* Found a lock context with lock requests */
+ break;
+ }
+
+ /* There is already a child waiting for the
+ * same key. So don't schedule another child
+ * just yet.
+ */
}
+ lock_ctx = next_ctx;
}
if (lock_ctx == NULL) {