summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2012-02-24 13:51:49 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2012-02-24 13:51:49 +1100
commit8692075c888c7671e2bcf372226a699971839c92 (patch)
tree3dbc28152759e846d627256c74e2da23adc6efb3
parent0af9456b31ed0ace37c13131dee29af8fa3ee665 (diff)
downloadmongo-8692075c888c7671e2bcf372226a699971839c92.tar.gz
Fix a livelock between an application thread with a page pinned and the eviction thread forcing it out.
-rw-r--r--src/btree/bt_evict.c17
1 files changed, 8 insertions, 9 deletions
diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c
index fd138c007b3..c6c6e10b699 100644
--- a/src/btree/bt_evict.c
+++ b/src/btree/bt_evict.c
@@ -350,20 +350,15 @@ __evict_request_walk(WT_SESSION_IMPL *session)
if (F_ISSET(er, WT_EVICT_REQ_PAGE)) {
WT_VERBOSE(session, evictserver,
"forcing eviction of page %p", er->page);
- for (;;) {
- ret = __wt_rec_evict(session, er->page, 0);
- if (ret != EBUSY)
- break;
- __wt_yield();
- }
+ ret = __wt_rec_evict(session, er->page, 0);
} else
ret = __evict_file(session, er);
+ __wt_spin_unlock(session, &cache->lru_lock);
+
/* Clear the reference to the btree handle. */
WT_CLEAR_BTREE_IN_SESSION(session);
- __wt_spin_unlock(session, &cache->lru_lock);
-
/*
* Resolve the request and clear the slot.
*
@@ -374,7 +369,11 @@ __evict_request_walk(WT_SESSION_IMPL *session)
if (!F_ISSET(er, WT_EVICT_REQ_PAGE))
__wt_session_serialize_wrapup(
request_session, NULL, ret);
-
+ else if (ret == EBUSY) {
+ /* Don't rest until this request is handled. */
+ __wt_cond_signal(session, cache->evict_cond);
+ continue;
+ }
__evict_req_clr(session, er);
}
return (0);