diff options
author | Amitay Isaacs <amitay@gmail.com> | 2013-08-02 10:54:38 +1000 |
---|---|---|
committer | Amitay Isaacs <amitay@gmail.com> | 2013-08-09 11:04:55 +1000 |
commit | 477a51aba5e36324263614cad6bef5d4c4c98942 (patch) | |
tree | 31a4726fe8409a89f7089c8c0d89c2fbfb29f581 /ctdb/server/ctdb_lock.c | |
parent | 9ba793a80ff489ba5ec40b3a55bef5f97aac634e (diff) | |
download | samba-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.c | 21 |
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) { |