diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-03-11 14:32:29 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2012-03-11 14:32:29 +1100 |
commit | 3515cdc3f4452fd89e58095f90e7934312ef930b (patch) | |
tree | d48222fa2b66e7cd23adbaaa167178f0ded7854c | |
parent | a5f3b8e7d3cbdb91b252f31a9a0a9daf7fa3f0b1 (diff) | |
download | mongo-3515cdc3f4452fd89e58095f90e7934312ef930b.tar.gz |
Always have an exclusive lock on btree handles before calling __wt_conn_btree_close, apart from the conn->close case which is inherently single-threaded.
-rw-r--r-- | src/conn/conn_btree.c | 16 | ||||
-rw-r--r-- | src/include/extern.h | 5 | ||||
-rw-r--r-- | src/session/session_api.c | 2 | ||||
-rw-r--r-- | src/session/session_btree.c | 6 |
4 files changed, 15 insertions, 14 deletions
diff --git a/src/conn/conn_btree.c b/src/conn/conn_btree.c index fb72d226139..556905644b7 100644 --- a/src/conn/conn_btree.c +++ b/src/conn/conn_btree.c @@ -117,11 +117,10 @@ conf: session->btree = btree; ret = __wt_btree_open(session, cfg, flags); if (ret == 0) F_SET(btree, WT_BTREE_OPEN); - __wt_rwunlock(session, btree->rwlock); - if (ret == 0) - return (0); + else + (void)__wt_conn_btree_close(session, 1); - (void)__wt_conn_btree_close(session); + __wt_rwunlock(session, btree->rwlock); return (ret); } @@ -130,7 +129,7 @@ conf: session->btree = btree; * Discard a reference to an open btree file handle. */ int -__wt_conn_btree_close(WT_SESSION_IMPL *session) +__wt_conn_btree_close(WT_SESSION_IMPL *session, int locked) { WT_BTREE *btree; WT_CONNECTION_IMPL *conn; @@ -157,14 +156,15 @@ __wt_conn_btree_close(WT_SESSION_IMPL *session) */ __wt_spin_lock(session, &conn->spinlock); inuse = --btree->refcnt > 0; - if (!inuse) + if (!inuse && !locked) __wt_writelock(session, btree->rwlock); __wt_spin_unlock(session, &conn->spinlock); if (!inuse) { ret = __wt_btree_close(session); F_CLR(btree, WT_BTREE_OPEN); - __wt_rwunlock(session, btree->rwlock); + if (!locked) + __wt_rwunlock(session, btree->rwlock); } return (ret); @@ -238,7 +238,7 @@ restart: * schema file entry, for good. */ while ((btree_session = TAILQ_FIRST(&session->btrees)) != NULL) - WT_TRET(__wt_session_remove_btree(session, btree_session)); + WT_TRET(__wt_session_remove_btree(session, btree_session, 0)); /* Close the schema file handle. */ while ((btree = TAILQ_FIRST(&conn->btqh)) != NULL) { diff --git a/src/include/extern.h b/src/include/extern.h index 0c59514af21..3ed526cb11c 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -438,7 +438,7 @@ extern int __wt_conn_btree_open(WT_SESSION_IMPL *session, const char *config, const char *cfg[], uint32_t flags); -extern int __wt_conn_btree_close(WT_SESSION_IMPL *session); +extern int __wt_conn_btree_close(WT_SESSION_IMPL *session, int locked); extern int __wt_conn_btree_remove(WT_CONNECTION_IMPL *conn); extern int __wt_conn_btree_reopen( WT_SESSION_IMPL *session, const char *cfg[], @@ -758,7 +758,8 @@ extern int __wt_session_get_btree(WT_SESSION_IMPL *session, const char *cfg[], uint32_t flags); extern int __wt_session_remove_btree( WT_SESSION_IMPL *session, - WT_BTREE_SESSION *btree_session); + WT_BTREE_SESSION *btree_session, + int locked); extern int __wt_session_close_any_open_btree(WT_SESSION_IMPL *session, const char *name); extern void __wt_eventv(WT_SESSION_IMPL *session, diff --git a/src/session/session_api.c b/src/session/session_api.c index 73568bfdb7e..e57aa124add 100644 --- a/src/session/session_api.c +++ b/src/session/session_api.c @@ -38,7 +38,7 @@ __session_close(WT_SESSION *wt_session, const char *config) WT_TRET(cursor->close(cursor)); while ((btree_session = TAILQ_FIRST(&session->btrees)) != NULL) - WT_TRET(__wt_session_remove_btree(session, btree_session)); + WT_TRET(__wt_session_remove_btree(session, btree_session, 0)); WT_TRET(__wt_schema_close_tables(session)); diff --git a/src/session/session_btree.c b/src/session/session_btree.c index a3dad604379..5bc6f4cffe9 100644 --- a/src/session/session_btree.c +++ b/src/session/session_btree.c @@ -175,13 +175,13 @@ __wt_session_get_btree(WT_SESSION_IMPL *session, */ int __wt_session_remove_btree( - WT_SESSION_IMPL *session, WT_BTREE_SESSION *btree_session) + WT_SESSION_IMPL *session, WT_BTREE_SESSION *btree_session, int locked) { TAILQ_REMOVE(&session->btrees, btree_session, q); session->btree = btree_session->btree; __wt_free(session, btree_session); - return (__wt_conn_btree_close(session)); + return (__wt_conn_btree_close(session, locked)); } /* @@ -205,7 +205,7 @@ __wt_session_close_any_open_btree(WT_SESSION_IMPL *session, const char *name) */ WT_ASSERT(session, btree_session->btree->refcnt == 1); __wt_schema_detach_tree(session, btree_session->btree); - ret = __wt_session_remove_btree(session, btree_session); + ret = __wt_session_remove_btree(session, btree_session, 1); __wt_rwunlock(session, session->btree->rwlock); } else if (ret == WT_NOTFOUND) ret = 0; |