Skip to content

Commit a0e4a75

Browse files
dormandodustin
authored andcommitted
fix resumption of accept loop under multithread
critical fix: under multithreaded mode, in version 1.2.7, memcached would not resume accepting connections after hitting the max connections limit. this is due to a pre-existing bug in the accept_new_conns code, which was hit when the "fix" was rolled in to ensure listening threads never did real work. Previously, at least one closing connection would (randomly) be on the accepting thread, so the test for (are we the listening thread?) would still work.
1 parent beb175a commit a0e4a75

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

memcached.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ static void settings_init(void);
8686
static void event_handler(const int fd, const short which, void *arg);
8787
static void conn_close(conn *c);
8888
static void conn_init(void);
89-
static void accept_new_conns(const bool do_accept);
9089
static bool update_event(conn *c, const int new_flags);
9190
static void complete_nread(conn *c);
9291
static void process_command(conn *c, char *command);
@@ -3073,12 +3072,9 @@ static bool update_event(conn *c, const int new_flags) {
30733072
/*
30743073
* Sets whether we are listening for new connections or not.
30753074
*/
3076-
void accept_new_conns(const bool do_accept) {
3075+
void do_accept_new_conns(const bool do_accept) {
30773076
conn *next;
30783077

3079-
if (! is_listen_thread())
3080-
return;
3081-
30823078
for (next = listen_conn; next; next = next->next) {
30833079
if (do_accept) {
30843080
update_event(next, EV_READ | EV_PERSIST);

memcached.h

+2
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ extern volatile rel_time_t current_time;
359359
/*
360360
* Functions
361361
*/
362+
void do_accept_new_conns(const bool do_accept);
362363
char *do_add_delta(conn *c, item *item, const bool incr, const int64_t delta,
363364
char *buf);
364365
enum store_item_type do_store_item(item *item, int comm, conn* c);
@@ -388,6 +389,7 @@ void dispatch_conn_new(int sfd, enum conn_states init_state, int event_flags, in
388389
/* Lock wrappers for cache functions that are called from main loop. */
389390
char *add_delta(conn *c, item *item, const int incr, const int64_t delta,
390391
char *buf);
392+
void accept_new_conns(const bool do_accept);
391393
conn *conn_from_freelist(void);
392394
bool conn_add_to_freelist(conn *c);
393395
char *suffix_from_freelist(void);

thread.c

+11
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ struct conn_queue {
3636
/* Lock for cache operations (item_*, assoc_*) */
3737
pthread_mutex_t cache_lock;
3838

39+
/* Connection lock around accepting new connections */
40+
pthread_mutex_t conn_lock = PTHREAD_MUTEX_INITIALIZER;
41+
3942
/* Lock for global stats */
4043
static pthread_mutex_t stats_lock;
4144

@@ -171,6 +174,14 @@ static void create_worker(void *(*func)(void *), void *arg) {
171174
}
172175
}
173176

177+
/*
178+
* Sets whether or not we accept new connections.
179+
*/
180+
void accept_new_conns(const bool do_accept) {
181+
pthread_mutex_lock(&conn_lock);
182+
do_accept_new_conns(do_accept);
183+
pthread_mutex_unlock(&conn_lock);
184+
}
174185
/****************************** LIBEVENT THREADS *****************************/
175186

176187
/*

0 commit comments

Comments
 (0)