summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2012-06-08 13:56:24 +1000
committerMichael Cahill <michael.cahill@wiredtiger.com>2012-06-08 13:56:24 +1000
commit97fd6ca26ef80d25d7229298edeaf4d46453f35b (patch)
tree843dc63f016093b350907c0e11c7fa9d8a0f03f5
parentc6103a38b1c0cce5a3aee30412946137a8b7dc05 (diff)
downloadmongo-97fd6ca26ef80d25d7229298edeaf4d46453f35b.tar.gz
Avoid a deadlock between eviction and checkpoint on the connection spinlock.
-rw-r--r--src/btree/bt_evict.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c
index a478cf16edf..064106d29c9 100644
--- a/src/btree/bt_evict.c
+++ b/src/btree/bt_evict.c
@@ -724,8 +724,12 @@ __evict_walk(WT_SESSION_IMPL *session)
* We hold a spinlock for the entire walk -- it's slow, but (1) how
* often do new files get added or removed to/from the system, and (2)
* it's all in-memory stuff, so it's not that slow.
+ *
+ * If the connection spinlock is not available, don't block: another
+ * thread may be holding it and waiting on eviction (e.g., checkpoint).
*/
- __wt_spin_lock(session, &conn->spinlock);
+ if (__wt_spin_trylock(session, &conn->spinlock) != 0)
+ return (0);
/*
* Resize the array in which we're tracking pages, as necessary, then
@@ -734,8 +738,8 @@ __evict_walk(WT_SESSION_IMPL *session)
*/
elem = WT_EVICT_WALK_BASE + (conn->btqcnt * WT_EVICT_WALK_PER_TABLE);
if (elem > cache->evict_entries) {
- /* Save the offset of the eviction point. */
__wt_spin_lock(session, &cache->evict_lock);
+ /* Save the offset of the eviction point. */
i = (u_int)(cache->evict_current - cache->evict);
WT_ERR(__wt_realloc(session, &cache->evict_allocated,
elem * sizeof(WT_EVICT_ENTRY), &cache->evict));