diff options
-rw-r--r-- | memcached.c | 19 | ||||
-rw-r--r-- | memcached.h | 3 | ||||
-rw-r--r-- | thread.c | 14 |
3 files changed, 27 insertions, 9 deletions
diff --git a/memcached.c b/memcached.c index 2592b3f..dd52dd0 100644 --- a/memcached.c +++ b/memcached.c @@ -939,6 +939,18 @@ static void conn_close(conn *c) { return; } +// Since some connections might be off on side threads and some are managed as +// listeners we need to walk through them all from a central point. +// Must be called with all worker threads hung or in the process of closing. +void conn_close_all(void) { + int i; + for (i = 0; i < max_fds; i++) { + if (conns[i] && conns[i]->state != conn_closed) { + conn_close(conns[i]); + } + } +} + /** * Convert a state name to a human readable form. */ @@ -10126,13 +10138,6 @@ int main (int argc, char **argv) { fprintf(stderr, "Gracefully stopping\n"); stop_threads(); - int i; - // FIXME: make a function callable from threads.c - for (i = 0; i < max_fds; i++) { - if (conns[i] && conns[i]->state != conn_closed) { - conn_close(conns[i]); - } - } if (memory_file != NULL) { restart_mmap_close(); } diff --git a/memcached.h b/memcached.h index a3ddd88..bdc38bd 100644 --- a/memcached.h +++ b/memcached.h @@ -820,9 +820,8 @@ enum delta_result_type add_delta(conn *c, const char *key, const int64_t delta, char *buf, uint64_t *cas); void accept_new_conns(const bool do_accept); -conn *conn_from_freelist(void); -bool conn_add_to_freelist(conn *c); void conn_close_idle(conn *c); +void conn_close_all(void); item *item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbytes); #define DO_UPDATE true #define DONT_UPDATE false @@ -204,6 +204,7 @@ void stop_threads(void) { if (settings.verbose > 0) fprintf(stderr, "asking workers to stop\n"); buf[0] = 's'; + pthread_mutex_lock(&worker_hang_lock); pthread_mutex_lock(&init_lock); init_count = 0; for (i = 0; i < settings.num_threads; i++) { @@ -215,6 +216,8 @@ void stop_threads(void) { wait_for_thread_registration(settings.num_threads); pthread_mutex_unlock(&init_lock); + // All of the workers are hung but haven't done cleanup yet. + if (settings.verbose > 0) fprintf(stderr, "asking background threads to stop\n"); @@ -236,6 +239,17 @@ void stop_threads(void) { if (settings.verbose > 0) fprintf(stderr, "stopped idle timeout thread\n"); + // Close all connections then let the workers finally exit. + if (settings.verbose > 0) + fprintf(stderr, "closing connections\n"); + conn_close_all(); + pthread_mutex_unlock(&worker_hang_lock); + if (settings.verbose > 0) + fprintf(stderr, "reaping worker threads\n"); + for (i = 0; i < settings.num_threads; i++) { + pthread_join(threads[i].thread_id, NULL); + } + if (settings.verbose > 0) fprintf(stderr, "all background threads stopped\n"); |