summaryrefslogtreecommitdiff
path: root/src/btree/bt_evict.c
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2014-11-14 17:53:52 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2014-11-14 17:53:52 +1100
commite5b624b976429cd1dd3dc6a4ac90fc9c5e58aed3 (patch)
treec3abf8b8d598d538b718069a7800e2e29cc4765f /src/btree/bt_evict.c
parent0df7b1e2684c33cc72b702d3563e4f155161ff10 (diff)
downloadmongo-e5b624b976429cd1dd3dc6a4ac90fc9c5e58aed3.tar.gz
Drop the handle lock while waiting for the eviction server to clear walks. Otherwise we can livelock.
Diffstat (limited to 'src/btree/bt_evict.c')
-rw-r--r--src/btree/bt_evict.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c
index d26abfff379..57d658ab69f 100644
--- a/src/btree/bt_evict.c
+++ b/src/btree/bt_evict.c
@@ -567,16 +567,28 @@ __evict_tree_walk_clear(WT_SESSION_IMPL *session)
WT_BTREE *btree;
WT_CACHE *cache;
WT_DECL_RET;
+ int locked;
btree = S2BT(session);
cache = S2C(session)->cache;
- while (btree->evict_ref != NULL) {
+ /*
+ * Drop the handle lock if we are holding it: the eviction server needs
+ * it to find the handle and clear the walk point.
+ */
+ locked = F_ISSET(session, WT_SESSION_HANDLE_LIST_LOCKED);
+ if (locked)
+ __wt_spin_unlock(session, &S2C(session)->dhandle_lock);
+
+ while (btree->evict_ref != NULL && ret == 0) {
F_SET(cache, WT_EVICT_CLEAR_WALKS);
- WT_RET(__wt_cond_wait(
- session, cache->evict_waiter_cond, 100000));
+ ret = __wt_cond_wait(
+ session, cache->evict_waiter_cond, 100000);
}
+ if (locked)
+ __wt_spin_lock(session, &S2C(session)->dhandle_lock);
+
return (ret);
}