summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsueloverso <sue@mongodb.com>2016-06-06 18:29:33 -0400
committerMichael Cahill <michael.cahill@mongodb.com>2016-06-07 08:29:33 +1000
commit0ddc632665d6815fb18806a0802916fea2914d55 (patch)
tree80eda7834bbe30d340f4579f33bd046e9f722521
parentd58f67f7c6873592b0823dbe746340c43404ede3 (diff)
downloadmongo-0ddc632665d6815fb18806a0802916fea2914d55.tar.gz
WT-2685 Fix clear walk hazard pointer failure. (#2781)
Add missing WT_WITH_PASS_LOCK with call to clear walks on shutdown. Add an assertion in evict_clear_walk to confirm the lock is held.
-rw-r--r--src/evict/evict_lru.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c
index a243f3fe8cd..0c453c9856c 100644
--- a/src/evict/evict_lru.c
+++ b/src/evict/evict_lru.c
@@ -196,10 +196,14 @@ __evict_thread_run(void *arg)
__wt_spin_trylock(session, &cache->evict_pass_lock) == 0) {
/*
* Cannot use WT_WITH_PASS_LOCK because this is a try
- * lock. Fix when that is supported.
+ * lock. Fix when that is supported. We set the flag
+ * on both sessions because we may call clear_walk when
+ * we are walking with the walk session, locked.
*/
F_SET(session, WT_SESSION_LOCKED_PASS);
+ F_SET(cache->walk_session, WT_SESSION_LOCKED_PASS);
ret = __evict_server(session, &did_work);
+ F_CLR(cache->walk_session, WT_SESSION_LOCKED_PASS);
F_CLR(session, WT_SESSION_LOCKED_PASS);
__wt_spin_unlock(session, &cache->evict_pass_lock);
WT_ERR(ret);
@@ -214,12 +218,15 @@ __evict_thread_run(void *arg)
WT_ERR(__evict_helper(session));
}
- if (session == conn->evict_session)
+ if (session == conn->evict_session) {
/*
* The eviction server is shutting down: in case any trees are
* still open, clear all walks now so that they can be closed.
*/
- WT_ERR(__evict_clear_all_walks(session));
+ WT_WITH_PASS_LOCK(session, ret,
+ ret = __evict_clear_all_walks(session));
+ WT_ERR(ret);
+ }
WT_ERR(__wt_verbose(
session, WT_VERB_EVICTSERVER, "cache eviction thread exiting"));
@@ -712,6 +719,7 @@ __evict_clear_walk(WT_SESSION_IMPL *session)
btree = S2BT(session);
cache = S2C(session)->cache;
+ WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_PASS));
if (session->dhandle == cache->evict_file_next)
cache->evict_file_next = NULL;