summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2020-11-12 17:34:29 -0800
committerdormando <dormando@rydia.net>2020-11-12 17:34:29 -0800
commit2896cc6c49c2bcd064e00da8bdf0dcaf1a481e73 (patch)
tree879a97be4c49e94d02f29ca82dcfdba34b82408c
parent2251d98cd7ecb7dd4b2f58fe9b97f5799eb39edc (diff)
downloadmemcached-2896cc6c49c2bcd064e00da8bdf0dcaf1a481e73.tar.gz
idle_timeout: avoid long hangs during shutdown
the idle thread would sleep for up to the max timeout given before checking for active connections again. the new shutdown code waits on threads to be joined after a shutdown signal, which could end up hanging by the idle_timeout. this now instead uses a cond_timedwait call to allow a condition signal to wake up the thread to exit. this should be done for a few other threads that sleep without conditions (lru_maintainer?)
-rw-r--r--memcached.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/memcached.c b/memcached.c
index e60f2c3..e21c166 100644
--- a/memcached.c
+++ b/memcached.c
@@ -296,6 +296,8 @@ extern pthread_mutex_t conn_lock;
/* Connection timeout thread bits */
static pthread_t conn_timeout_tid;
static int do_run_conn_timeout_thread;
+static pthread_cond_t conn_timeout_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t conn_timeout_lock = PTHREAD_MUTEX_INITIALIZER;
#define CONNS_PER_SLICE 100
#define TIMEOUT_MSG_SIZE (1 + sizeof(int))
@@ -311,6 +313,7 @@ static void *conn_timeout_thread(void *arg) {
useconds_t timeslice = 1000000 / sleep_slice;
+ mutex_lock(&conn_timeout_lock);
while(do_run_conn_timeout_thread) {
if (settings.verbose > 2)
fprintf(stderr, "idle timeout thread at top of connection list\n");
@@ -357,9 +360,17 @@ static void *conn_timeout_thread(void *arg) {
fprintf(stderr,
"idle timeout thread finished pass, sleeping for %ds\n",
sleep_time);
- usleep((useconds_t) sleep_time * 1000000);
+
+ struct timeval now;
+ struct timespec to_sleep;
+ gettimeofday(&now, NULL);
+ to_sleep.tv_sec = now.tv_sec + sleep_time;
+ to_sleep.tv_nsec = 0;
+
+ pthread_cond_timedwait(&conn_timeout_cond, &conn_timeout_lock, &to_sleep);
}
+ mutex_unlock(&conn_timeout_lock);
return NULL;
}
@@ -383,7 +394,10 @@ static int start_conn_timeout_thread() {
int stop_conn_timeout_thread(void) {
if (!do_run_conn_timeout_thread)
return -1;
+ mutex_lock(&conn_timeout_lock);
do_run_conn_timeout_thread = 0;
+ pthread_cond_signal(&conn_timeout_cond);
+ mutex_unlock(&conn_timeout_lock);
pthread_join(conn_timeout_tid, NULL);
return 0;
}