summaryrefslogtreecommitdiff
path: root/src/evict/evict_lru.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/evict/evict_lru.c')
-rw-r--r--src/evict/evict_lru.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c
index 35b12e2b685..884c08a02df 100644
--- a/src/evict/evict_lru.c
+++ b/src/evict/evict_lru.c
@@ -791,7 +791,7 @@ __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session, bool *evict_resetp)
btree = S2BT(session);
cache = S2C(session)->cache;
- /* If the file wasn't evictable, there's no work to do. */
+ /* If the file was never evictable, there's no work to do. */
if (F_ISSET(btree, WT_BTREE_NO_EVICTION))
return (0);
@@ -800,9 +800,16 @@ __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session, bool *evict_resetp)
* the file will be queued for eviction after this point.
*/
__wt_spin_lock(session, &cache->evict_walk_lock);
- F_SET(btree, WT_BTREE_NO_EVICTION);
+ if (!F_ISSET(btree, WT_BTREE_NO_EVICTION)) {
+ F_SET(btree, WT_BTREE_NO_EVICTION);
+ *evict_resetp = true;
+ }
__wt_spin_unlock(session, &cache->evict_walk_lock);
+ /* If some other operation has disabled eviction, we're done. */
+ if (!*evict_resetp)
+ return (0);
+
/* Clear any existing LRU eviction walk for the file. */
WT_ERR(__evict_request_walk_clear(session));
@@ -826,10 +833,10 @@ __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session, bool *evict_resetp)
while (btree->evict_busy > 0)
__wt_yield();
- *evict_resetp = true;
return (0);
err: F_CLR(btree, WT_BTREE_NO_EVICTION);
+ *evict_resetp = false;
return (ret);
}
@@ -844,7 +851,14 @@ __wt_evict_file_exclusive_off(WT_SESSION_IMPL *session)
btree = S2BT(session);
- WT_ASSERT(session, btree->evict_ref == NULL);
+ /*
+ * We have seen subtle bugs with multiple threads racing to turn
+ * eviction on/off. Make races more likely in diagnostic builds.
+ */
+ WT_DIAGNOSTIC_YIELD;
+
+ WT_ASSERT(session, btree->evict_ref == NULL &&
+ F_ISSET(btree, WT_BTREE_NO_EVICTION));
F_CLR(btree, WT_BTREE_NO_EVICTION);
}