summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gorrod <alexander.gorrod@mongodb.com>2016-08-26 17:23:30 +1000
committerMichael Cahill <michael.cahill@mongodb.com>2016-08-26 17:23:30 +1000
commitec3faa736e3dc2eccd45eef3e1b8c6b1d32836d4 (patch)
treec02af27c4e2d6f9dc57a432dfc8661370fc8a845
parent92cde719d48d9978e93967643410b3f31c765580 (diff)
downloadmongo-ec3faa736e3dc2eccd45eef3e1b8c6b1d32836d4.tar.gz
Fix a bug in thread group shrink where it could leak memory. (#2987)
-rw-r--r--src/include/thread_group.h4
-rw-r--r--src/support/thread_group.c45
2 files changed, 20 insertions, 29 deletions
diff --git a/src/include/thread_group.h b/src/include/thread_group.h
index a0d1f68b85b..f946dcab144 100644
--- a/src/include/thread_group.h
+++ b/src/include/thread_group.h
@@ -25,9 +25,7 @@ struct __wt_thread {
* Flags for thread group functions.
*/
#define WT_THREAD_CAN_WAIT 0x01
-#define WT_THREAD_CLOSE_ALL 0x02
-#define WT_THREAD_FREE 0x04
-#define WT_THREAD_PANIC_FAIL 0x08
+#define WT_THREAD_PANIC_FAIL 0x02
/*
* WT_THREAD_GROUP --
diff --git a/src/support/thread_group.c b/src/support/thread_group.c
index 6b751814717..016956c527f 100644
--- a/src/support/thread_group.c
+++ b/src/support/thread_group.c
@@ -72,11 +72,12 @@ __thread_group_grow(
/*
* __thread_group_shrink --
- * Decrease the number of running threads in the group.
+ * Decrease the number of running threads in the group, and free any
+ * memory associated with slots larger than the new count.
*/
static int
__thread_group_shrink(WT_SESSION_IMPL *session,
- WT_THREAD_GROUP *group, uint32_t new_count, uint32_t flags)
+ WT_THREAD_GROUP *group, uint32_t new_count)
{
WT_DECL_RET;
WT_SESSION *wt_session;
@@ -86,12 +87,7 @@ __thread_group_shrink(WT_SESSION_IMPL *session,
WT_ASSERT(session,
__wt_rwlock_islocked(session, group->lock));
- if (LF_ISSET(WT_THREAD_CLOSE_ALL))
- current_slot = group->alloc;
- else
- current_slot = group->current_threads;
-
- while (current_slot > new_count) {
+ for (current_slot = group->alloc; current_slot > new_count; ) {
/*
* The offset value is a counter not an array index,
* so adjust it before finding the last thread in the group.
@@ -112,20 +108,15 @@ __thread_group_shrink(WT_SESSION_IMPL *session,
thread->tid = 0;
}
- /*
- * Worker thread sessions are only freed when shrinking the
- * pool or shutting down the connection.
- */
- if (LF_ISSET(WT_THREAD_FREE)) {
- if (thread->session != NULL) {
- wt_session = (WT_SESSION *)thread->session;
- WT_TRET(wt_session->close(wt_session, NULL));
- thread->session = NULL;
- }
- __wt_free(session, thread);
- group->threads[current_slot] = NULL;
+ if (thread->session != NULL) {
+ wt_session = (WT_SESSION *)thread->session;
+ WT_TRET(wt_session->close(wt_session, NULL));
+ thread->session = NULL;
}
+ __wt_free(session, thread);
+ group->threads[current_slot] = NULL;
}
+
/* Update the thread group state to match our changes */
group->current_threads = current_slot;
return (ret);
@@ -156,9 +147,11 @@ __thread_group_resize(
if (new_min == group->min && new_max == group->max)
return (0);
- if (group->current_threads > new_max)
- WT_RET(__thread_group_shrink(
- session, group, new_max, WT_THREAD_FREE));
+ /*
+ * Coll shrink to reduce the number of thread structures and running
+ * threads if required by the change in group size.
+ */
+ WT_RET(__thread_group_shrink(session, group, new_max));
/*
* Only reallocate the thread array if it is the largest ever, since
@@ -193,6 +186,7 @@ __thread_group_resize(
F_SET(thread, WT_THREAD_PANIC_FAIL);
thread->id = i;
thread->run_func = group->run_func;
+ WT_ASSERT(session, group->threads[i] == NULL);
group->threads[i] = thread;
}
@@ -300,9 +294,8 @@ __wt_thread_group_destroy(
WT_ASSERT(session,
__wt_rwlock_islocked(session, group->lock));
- /* Shut down all threads. */
- WT_TRET(__thread_group_shrink(session,
- group, 0, WT_THREAD_CLOSE_ALL | WT_THREAD_FREE));
+ /* Shut down all threads and free associated resources. */
+ WT_TRET(__thread_group_shrink(session, group, 0));
__wt_free(session, group->threads);