summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2014-08-01 20:27:46 +1000
committerMichael Cahill <michael.cahill@wiredtiger.com>2014-08-01 20:27:46 +1000
commit0fe07119eb0df6b916dde47cb093587da659f342 (patch)
tree119818430bf1ae8122986d7e09455079e0652f68
parente9bba7b3fc4cf5376cc6f84006fc612701c00352 (diff)
downloadmongo-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.c72
-rw-r--r--src/conn/conn_cache.c2
-rw-r--r--src/include/cache.h3
-rw-r--r--src/include/connection.h2
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 */