summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsueloverso <sue@mongodb.com>2015-08-27 10:03:10 -0400
committerMichael Cahill <michael.cahill@mongodb.com>2015-09-18 12:48:53 +1000
commit119038d87461bde02631f577721fbfc1ec961c82 (patch)
treeb4bceb36ab0513f63157036000315a9757f6c51c
parent0661c0bff0e1fa7c5751397114b85cfa579a41a7 (diff)
downloadmongo-119038d87461bde02631f577721fbfc1ec961c82.tar.gz
WT-2064 Don't spin indefinitely waiting for the handle list lock in eviction
Merge pull request #2155 from wiredtiger/WT-2064 (cherry picked from commit 66757f72471ced8edd858c4dd2742e6318ed446a)
-rw-r--r--src/evict/evict_lru.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c
index 4dd63d09e0b..f077f168a26 100644
--- a/src/evict/evict_lru.c
+++ b/src/evict/evict_lru.c
@@ -158,6 +158,8 @@ __evict_server(void *arg)
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
WT_SESSION_IMPL *session;
+ u_int spins;
+ WT_DECL_SPINLOCK_ID(id);
session = arg;
conn = S2C(session);
@@ -175,8 +177,26 @@ __evict_server(void *arg)
* otherwise we can block applications evicting large pages.
*/
if (!F_ISSET(cache, WT_CACHE_STUCK)) {
- WT_WITH_DHANDLE_LOCK(session,
- ret = __evict_clear_all_walks(session));
+ for (spins = 0; (ret = __wt_spin_trylock(
+ session, &conn->dhandle_lock, &id)) == EBUSY &&
+ !F_ISSET(cache, WT_CACHE_CLEAR_WALKS);
+ spins++) {
+ if (spins < 1000)
+ __wt_yield();
+ else
+ __wt_sleep(0, 1000);
+ }
+ /*
+ * If we gave up acquiring the lock, that indicates a
+ * session is waiting for us to clear walks. Do that
+ * as part of a normal pass (without the handle list
+ * lock) to avoid deadlock.
+ */
+ if (ret == EBUSY)
+ continue;
+ WT_ERR(ret);
+ ret = __evict_clear_all_walks(session);
+ __wt_spin_unlock(session, &conn->dhandle_lock);
WT_ERR(ret);
/* Next time we wake up, reverse the sweep direction. */