diff options
author | Alex Gorrod <alexander.gorrod@mongodb.com> | 2016-08-26 17:23:30 +1000 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2016-08-26 17:23:30 +1000 |
commit | ec3faa736e3dc2eccd45eef3e1b8c6b1d32836d4 (patch) | |
tree | c02af27c4e2d6f9dc57a432dfc8661370fc8a845 | |
parent | 92cde719d48d9978e93967643410b3f31c765580 (diff) | |
download | mongo-ec3faa736e3dc2eccd45eef3e1b8c6b1d32836d4.tar.gz |
Fix a bug in thread group shrink where it could leak memory. (#2987)
-rw-r--r-- | src/include/thread_group.h | 4 | ||||
-rw-r--r-- | src/support/thread_group.c | 45 |
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); |