diff options
author | Volker Lendecke <vl@samba.org> | 2010-02-16 12:22:08 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2010-02-16 13:21:10 +0100 |
commit | 725b3654f831fbe0388cc09f46269903c9eef1d7 (patch) | |
tree | 0935e8d4d3246292bcf7cd4b1453bebb23e4f3a8 /source3/lib | |
parent | 07978bd175395e0dc770f68fff5b8bd8b0fdeb51 (diff) | |
download | samba-725b3654f831fbe0388cc09f46269903c9eef1d7.tar.gz samba-725b3654f831fbe0388cc09f46269903c9eef1d7.tar.bz2 samba-725b3654f831fbe0388cc09f46269903c9eef1d7.zip |
s3: Avoid a thundering herd in g_lock_unlock
Only notify the first 5 pending lock waiters. This avoids a thundering herd
problem that is really nasty in a cluster. It also makes acquiring a lock a bit
more FIFO, lock waiters are added to the end of the array.
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/g_lock.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c index e2620255d9..512c0680d9 100644 --- a/source3/lib/g_lock.c +++ b/source3/lib/g_lock.c @@ -530,13 +530,23 @@ static NTSTATUS g_lock_force_unlock(struct g_lock_ctx *ctx, const char *name, } if ((lock_type & G_LOCK_PENDING) == 0) { + int num_wakeups = 0; + /* - * We've been the lock holder. Tell all others to retry. + * We've been the lock holder. Others to retry. Don't + * tell all others to avoid a thundering herd. In case + * this leads to a complete stall because we miss some + * processes, the loop in g_lock_lock tries at least + * once a minute. */ + for (i=0; i<num_locks; i++) { if ((locks[i].lock_type & G_LOCK_PENDING) == 0) { continue; } + if (!process_exists(locks[i].pid)) { + continue; + } /* * Ping all waiters to retry @@ -549,6 +559,11 @@ static NTSTATUS g_lock_force_unlock(struct g_lock_ctx *ctx, const char *name, procid_str(talloc_tos(), &locks[i].pid), nt_errstr(status))); + } else { + num_wakeups += 1; + } + if (num_wakeups > 5) { + break; } } } |