summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2015-02-17 21:56:34 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2015-02-17 21:56:34 +1100
commitc34a56f357e21d134a2d9d0fefc032544069d8d7 (patch)
treed60b5ee0ad538795a25c5d4220813bc19e52f4ea
parenta9de0f7ac8ad373d7aef6a480c69a2a7e0b55c59 (diff)
downloadmongo-c34a56f357e21d134a2d9d0fefc032544069d8d7.tar.gz
Allow the maximum number of eviction threads to be reconfigured. This was previously permitted by the API, but the array of thread contexts was not correctly resized, leading to segfaults.
refs SERVER-17293
-rw-r--r--src/evict/evict_lru.c71
-rw-r--r--src/include/connection.h1
2 files changed, 47 insertions, 25 deletions
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c
index c6b962f9f5d..6d541e3ffb6 100644
--- a/src/evict/evict_lru.c
+++ b/src/evict/evict_lru.c
@@ -225,6 +225,47 @@ err: WT_PANIC_MSG(session, ret, "cache eviction server error");
}
/*
+ * __evict_workers_resize --
+ * Resize the array of eviction workers (as needed after a reconfigure).
+ * We don't do this during the reconfigure because the eviction server
+ * thread owns these structures.
+ */
+static int
+__evict_workers_resize(WT_SESSION_IMPL *session)
+{
+ WT_CONNECTION_IMPL *conn;
+ WT_DECL_RET;
+ WT_EVICT_WORKER *workers;
+ size_t alloc;
+ u_int i;
+
+ conn = S2C(session);
+
+ alloc = conn->evict_workers_alloc * sizeof(*workers);
+ WT_RET(__wt_realloc(session, &alloc,
+ conn->evict_workers_max * sizeof(*workers), &conn->evict_workctx));
+ workers = conn->evict_workctx;
+
+ for (i = conn->evict_workers_alloc; i < conn->evict_workers_max; i++) {
+ WT_ERR(__wt_open_internal_session(conn,
+ "eviction-worker", 0, 0, &workers[i].session));
+ workers[i].id = i;
+ F_SET(workers[i].session, WT_SESSION_CAN_WAIT);
+
+ if (i < conn->evict_workers_min) {
+ ++conn->evict_workers;
+ F_SET(&workers[i], WT_EVICT_WORKER_RUN);
+ WT_ERR(__wt_thread_create(
+ workers[i].session, &workers[i].tid,
+ __evict_worker, &workers[i]));
+ }
+ }
+
+err: conn->evict_workers_alloc = conn->evict_workers_max;
+ return (ret);
+}
+
+/*
* __wt_evict_create --
* Start the eviction server thread.
*/
@@ -232,8 +273,6 @@ int
__wt_evict_create(WT_SESSION_IMPL *session)
{
WT_CONNECTION_IMPL *conn;
- WT_EVICT_WORKER *workers;
- u_int i;
conn = S2C(session);
@@ -253,27 +292,6 @@ __wt_evict_create(WT_SESSION_IMPL *session)
if (conn->evict_workers_max == 0)
F_SET(session, WT_SESSION_CAN_WAIT);
- if (conn->evict_workers_max > 0) {
- WT_RET(__wt_calloc_def(
- session, conn->evict_workers_max, &workers));
- conn->evict_workctx = workers;
-
- for (i = 0; i < conn->evict_workers_max; i++) {
- WT_RET(__wt_open_internal_session(conn,
- "eviction-worker", 0, 0, &workers[i].session));
- workers[i].id = i;
- F_SET(workers[i].session, WT_SESSION_CAN_WAIT);
-
- if (i < conn->evict_workers_min) {
- ++conn->evict_workers;
- F_SET(&workers[i], WT_EVICT_WORKER_RUN);
- WT_RET(__wt_thread_create(
- workers[i].session, &workers[i].tid,
- __evict_worker, &workers[i]));
- }
- }
- }
-
/*
* Start the primary eviction server thread after the worker threads
* have started to avoid it starting additional worker threads before
@@ -314,9 +332,10 @@ __wt_evict_destroy(WT_SESSION_IMPL *session)
}
/* Handle shutdown when cleaning up after a failed open */
if (conn->evict_workctx != NULL) {
- for (i = 0; i < conn->evict_workers_max; i++) {
+ for (i = 0; i < conn->evict_workers_alloc; i++) {
wt_session = &conn->evict_workctx[i].session->iface;
- WT_TRET(wt_session->close(wt_session, NULL));
+ if (wt_session != NULL)
+ WT_TRET(wt_session->close(wt_session, NULL));
}
__wt_free(session, conn->evict_workctx);
}
@@ -479,6 +498,8 @@ __evict_pass(WT_SESSION_IMPL *session)
WT_RET(__wt_verbose(session, WT_VERB_EVICTSERVER,
"Starting evict worker: %"PRIu32"\n",
conn->evict_workers));
+ if (conn->evict_workers >= conn->evict_workers_alloc)
+ WT_RET(__evict_workers_resize(session));
worker = &conn->evict_workctx[conn->evict_workers++];
F_SET(worker, WT_EVICT_WORKER_RUN);
WT_RET(__wt_thread_create(session,
diff --git a/src/include/connection.h b/src/include/connection.h
index ff5e401fadd..5e69c93cfce 100644
--- a/src/include/connection.h
+++ b/src/include/connection.h
@@ -290,6 +290,7 @@ struct __wt_connection_impl {
wt_thread_t evict_tid; /* Eviction server thread ID */
int evict_tid_set; /* Eviction server thread ID set */
+ uint32_t evict_workers_alloc;/* Allocated eviction workers */
uint32_t evict_workers_max;/* Max eviction workers */
uint32_t evict_workers_min;/* Min eviction workers */
uint32_t evict_workers; /* Number of eviction workers */