diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2014-08-01 20:27:46 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2014-08-01 20:27:46 +1000 |
commit | 0fe07119eb0df6b916dde47cb093587da659f342 (patch) | |
tree | 119818430bf1ae8122986d7e09455079e0652f68 | |
parent | e9bba7b3fc4cf5376cc6f84006fc612701c00352 (diff) | |
download | mongo-0fe07119eb0df6b916dde47cb093587da659f342.tar.gz |
Move session creation out of worker threads: the session open can race with connection close.
-rw-r--r-- | src/btree/bt_evict.c | 72 | ||||
-rw-r--r-- | src/conn/conn_cache.c | 2 | ||||
-rw-r--r-- | src/include/cache.h | 3 | ||||
-rw-r--r-- | src/include/connection.h | 2 |
4 files changed, 43 insertions, 36 deletions
diff --git a/src/btree/bt_evict.c b/src/btree/bt_evict.c index 1637b447c9a..78933a6ab32 100644 --- a/src/btree/bt_evict.c +++ b/src/btree/bt_evict.c @@ -18,7 +18,7 @@ static int __evict_walk_file(WT_SESSION_IMPL *, u_int *, uint32_t); static void *__evict_worker(void *); typedef struct { - WT_CONNECTION_IMPL *conn; + WT_SESSION_IMPL *session; u_int id; pthread_t tid; @@ -157,25 +157,11 @@ __evict_server(void *arg) WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_DECL_RET; - WT_EVICTION_WORKER *workers; WT_SESSION_IMPL *session; - u_int i; session = arg; conn = S2C(session); cache = conn->cache; - workers = NULL; - - if (cache->eviction_workers > 0) - WT_ERR(__wt_calloc_def( - session, cache->eviction_workers, &workers)); - - for (i = 0; i < cache->eviction_workers; i++) { - workers[i].conn = conn; - workers[i].id = i; - WT_ERR(__wt_thread_create(session, - &workers[i].tid, __evict_worker, &workers[i])); - } while (F_ISSET(conn, WT_CONN_EVICTION_RUN)) { /* Evict pages from the cache as needed. */ @@ -194,14 +180,7 @@ __evict_server(void *arg) WT_ERR(__wt_verbose(session, WT_VERB_EVICTSERVER, "exiting")); -err: WT_TRET(__wt_verbose( - session, WT_VERB_EVICTSERVER, "waiting for helper threads")); - for (i = 0; i < cache->eviction_workers; i++) { - WT_TRET(__wt_cond_signal(session, cache->evict_waiter_cond)); - WT_TRET(__wt_thread_join(session, workers[i].tid)); - } - __wt_free(session, workers); - +err: if (ret != 0) { WT_PANIC_MSG(session, ret, "eviction server error"); return (NULL); @@ -233,15 +212,35 @@ err: WT_TRET(__wt_verbose( int __wt_evict_create(WT_CONNECTION_IMPL *conn) { + WT_CACHE *cache; WT_SESSION_IMPL *session; + WT_EVICTION_WORKER *workers; + u_int i; + + cache = conn->cache; /* Set first, the thread might run before we finish up. */ F_SET(conn, WT_CONN_EVICTION_RUN); + /* We need a session handle because we're reading/writing pages. */ WT_RET(__wt_open_internal_session( conn, "eviction-server", 0, 0, &session)); conn->evict_session = session; + if (cache->eviction_nworkers > 0) { + WT_RET(__wt_calloc_def( + session, cache->eviction_nworkers, &workers)); + cache->eviction_workers = workers; + } + + for (i = 0; i < cache->eviction_nworkers; i++) { + WT_RET(__wt_open_internal_session( + conn, "eviction-worker", 0, 0, &workers[i].session)); + workers[i].id = i; + WT_RET(__wt_thread_create(session, + &workers[i].tid, __evict_worker, &workers[i])); + } + WT_RET(__wt_thread_create( session, &conn->evict_tid, __evict_server, conn->evict_session)); conn->evict_tid_set = 1; @@ -256,13 +255,27 @@ __wt_evict_create(WT_CONNECTION_IMPL *conn) int __wt_evict_destroy(WT_CONNECTION_IMPL *conn) { + WT_CACHE *cache; WT_DECL_RET; + WT_EVICTION_WORKER *workers; WT_SESSION *wt_session; WT_SESSION_IMPL *session; + u_int i; + cache = conn->cache; session = conn->default_session; + workers = cache->eviction_workers; F_CLR(conn, WT_CONN_EVICTION_RUN); + + WT_TRET(__wt_verbose( + session, WT_VERB_EVICTSERVER, "waiting for helper threads")); + for (i = 0; i < cache->eviction_nworkers; i++) { + WT_TRET(__wt_cond_signal(session, cache->evict_waiter_cond)); + WT_TRET(__wt_thread_join(session, workers[i].tid)); + } + __wt_free(session, workers); + if (conn->evict_tid_set) { WT_TRET(__wt_evict_server_wake(session)); WT_TRET(__wt_thread_join(session, conn->evict_tid)); @@ -293,17 +306,10 @@ __evict_worker(void *arg) uint32_t flags; worker = arg; - conn = worker->conn; + session = worker->session; + conn = S2C(session); cache = conn->cache; - /* - * We need a session handle because we're reading/writing pages. - * Start with the default session to keep error handling simple. - */ - session = conn->default_session; - WT_ERR(__wt_open_internal_session( - conn, "eviction-worker", 0, 0, &session)); - while (F_ISSET(conn, WT_CONN_EVICTION_RUN)) { /* Don't spin in a busy loop if there is no work to do */ WT_ERR(__evict_has_work(session, &flags)); @@ -723,7 +729,7 @@ __evict_lru(WT_SESSION_IMPL *session, uint32_t flags) */ WT_RET(__wt_cond_signal(session, cache->evict_waiter_cond)); - if (cache->eviction_workers > 0) { + if (cache->eviction_nworkers > 0) { WT_STAT_FAST_CONN_INCR( session, cache_eviction_server_not_evicting); /* diff --git a/src/conn/conn_cache.c b/src/conn/conn_cache.c index 4eb6391334e..0870724b0d9 100644 --- a/src/conn/conn_cache.c +++ b/src/conn/conn_cache.c @@ -56,7 +56,7 @@ __wt_cache_config(WT_CONNECTION_IMPL *conn, const char *cfg[]) if ((ret = __wt_config_gets(session, cfg, "eviction_workers", &cval)) == 0) - cache->eviction_workers = (u_int)cval.val; + cache->eviction_nworkers = (u_int)cval.val; WT_RET_NOTFOUND_OK(ret); return (0); diff --git a/src/include/cache.h b/src/include/cache.h index bbe4157aadf..98154e41a7e 100644 --- a/src/include/cache.h +++ b/src/include/cache.h @@ -65,7 +65,8 @@ struct __wt_cache { u_int eviction_target; /* Percent to end eviction */ u_int eviction_dirty_target; /* Percent to allow dirty */ - u_int eviction_workers; /* Additional eviction threads */ + u_int eviction_nworkers; /* Additional eviction threads */ + void *eviction_workers; /* Eviction worker context */ /* * LRU eviction list information. diff --git a/src/include/connection.h b/src/include/connection.h index 18a825111c8..c22a55b6b7a 100644 --- a/src/include/connection.h +++ b/src/include/connection.h @@ -199,7 +199,7 @@ struct __wt_connection_impl { uint32_t async_size; /* Async op array size */ uint32_t async_workers; /* Number of async workers */ - WT_SESSION_IMPL *evict_session; /* Eviction server session */ + WT_SESSION_IMPL *evict_session; /* Eviction server sessions */ pthread_t evict_tid; /* Eviction server thread ID */ int evict_tid_set; /* Eviction server thread ID set */ |