diff options
author | Volker Lendecke <vl@samba.org> | 2010-02-15 16:57:16 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2010-02-16 13:21:10 +0100 |
commit | 07978bd175395e0dc770f68fff5b8bd8b0fdeb51 (patch) | |
tree | 82eb86cf2e0c3bc2ff70815bd9262df291146caf | |
parent | f3bdb163f461175c50b4930fa3464beaee30f4a8 (diff) | |
download | samba-07978bd175395e0dc770f68fff5b8bd8b0fdeb51.tar.gz samba-07978bd175395e0dc770f68fff5b8bd8b0fdeb51.tar.bz2 samba-07978bd175395e0dc770f68fff5b8bd8b0fdeb51.zip |
s3: Optimize g_lock_lock for a heavily contended case
Only check the existence of the lock owner in g_lock_parse, check the rest of
the records only when we got the lock successfully. This reduces the load on
process_exists which can involve a network roundtrip in the clustered case.
-rw-r--r-- | source3/lib/g_lock.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c index 42c0397189..e2620255d9 100644 --- a/source3/lib/g_lock.c +++ b/source3/lib/g_lock.c @@ -108,6 +108,34 @@ static bool g_lock_parse(TALLOC_CTX *mem_ctx, TDB_DATA data, (locks[i].lock_type & G_LOCK_PENDING) ? "(pending)" : "(owner)")); + if (((locks[i].lock_type & G_LOCK_PENDING) == 0) + && !process_exists(locks[i].pid)) { + + DEBUGADD(10, ("lock owner %s died -- discarding\n", + procid_str(talloc_tos(), + &locks[i].pid))); + + if (i < (num_locks-1)) { + locks[i] = locks[num_locks-1]; + } + num_locks -= 1; + } + } + + *plocks = locks; + *pnum_locks = num_locks; + return true; +} + +static void g_lock_cleanup(int *pnum_locks, struct g_lock_rec *locks) +{ + int i, num_locks; + + num_locks = *pnum_locks; + + DEBUG(10, ("g_lock_cleanup: %d locks\n", num_locks)); + + for (i=0; i<num_locks; i++) { if (process_exists(locks[i].pid)) { continue; } @@ -119,10 +147,8 @@ static bool g_lock_parse(TALLOC_CTX *mem_ctx, TDB_DATA data, } num_locks -= 1; } - - *plocks = locks; *pnum_locks = num_locks; - return true; + return; } static struct g_lock_rec *g_lock_addrec(TALLOC_CTX *mem_ctx, @@ -239,6 +265,13 @@ again: locks[our_index].lock_type = lock_type; } + if (NT_STATUS_IS_OK(status) && ((lock_type & G_LOCK_PENDING) == 0)) { + /* + * Walk through the list of locks, search for dead entries + */ + g_lock_cleanup(&num_locks, locks); + } + data = make_tdb_data((uint8_t *)locks, num_locks * sizeof(*locks)); store_status = rec->store(rec, data, 0); if (!NT_STATUS_IS_OK(store_status)) { |