diff options
-rw-r--r-- | src/evict/evict_lru.c | 24 |
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. */ |