Permalink
Browse files

Fix incredibly slim race for maxconns handler

I am an idiot: inbetween setting allow_new_conns -> false and calling the
maxconns subroutine, another thread could have already flipped it back. This
is probably due to a lack of strict memory barriers allowing the assignments
to the allow_new_conns variable to be reordered outside of the lock.

Instead of copy/pasting the handler enabler code, we now treat an fd argument
of -42 as special and force the callback to run once. Normally fd is -1 since there's no associated socket for the callback.
  • Loading branch information...
dormando committed Jul 27, 2011
1 parent d07bfbe commit 2c56090933e01ea5ab7d0c6e6530ea73b0933cf9
Showing with 2 additions and 2 deletions.
  1. +2 −2 memcached.c
View
@@ -130,7 +130,7 @@ static struct event maxconnsevent;
static void maxconns_handler(const int fd, const short which, void *arg) {
struct timeval t = {.tv_sec = 0, .tv_usec = 10000};
- if (allow_new_conns == false) {
+ if (fd == -42 || allow_new_conns == false) {
/* reschedule in 10ms if we need to keep polling */
evtimer_set(&maxconnsevent, maxconns_handler, 0);
event_base_set(main_base, &maxconnsevent);
@@ -3386,7 +3386,7 @@ void do_accept_new_conns(const bool do_accept) {
stats.listen_disabled_num++;
STATS_UNLOCK();
allow_new_conns = false;
- maxconns_handler(0, 0, 0);
+ maxconns_handler(-42, 0, 0);
}
}

0 comments on commit 2c56090

Please sign in to comment.