Skip to content

Commit

Permalink
Be more graceful with too many connections.
Browse files Browse the repository at this point in the history
Fixes bug beanstalkd#587.
  • Loading branch information
Keith Rarick committed Nov 7, 2007
1 parent 6f84c28 commit ec812a1
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 9 deletions.
17 changes: 9 additions & 8 deletions beanstalkd.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>

#include "conn.h"
#include "net.h"
Expand Down Expand Up @@ -649,6 +650,7 @@ h_accept(const int fd, const short which, struct event *ev)
cfd = accept(fd, &addr, &addrlen);
if (cfd == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) twarn("accept()");
if (errno == EMFILE) brake();
return;
}

Expand All @@ -659,21 +661,20 @@ h_accept(const int fd, const short which, struct event *ev)
if (r < 0) return twarn("setting O_NONBLOCK"), close(cfd), v();

c = make_conn(cfd, STATE_WANTCOMMAND);
if (!c) return twarnx("make_conn() failed"), close(cfd), v();
if (!c) return twarnx("make_conn() failed"), close(cfd), brake();

dprintf("accepted conn, fd=%d\n", cfd);
r = conn_set_evq(c, EV_READ | EV_PERSIST, (evh) h_conn);
if (r == -1) return twarnx("conn_set_evq() failed"), close(cfd), v();
if (r == -1) return twarnx("conn_set_evq() failed"), close(cfd), brake();
}

int
main(int argc, char **argv)
{
int listen_socket;
struct event listen_evq;
int r;

listen_socket = make_server_socket(HOST, PORT);
if (listen_socket == -1) twarnx("make_server_socket()"), exit(111);
r = make_server_socket(HOST, PORT);
if (r == -1) twarnx("make_server_socket()"), exit(111);

prot_init();
#ifndef DEBUG
Expand All @@ -682,9 +683,9 @@ main(int argc, char **argv)
event_init();
set_sig_handlers();

event_set(&listen_evq, listen_socket, EV_READ | EV_PERSIST, (evh) h_accept, &listen_evq);
event_add(&listen_evq, NULL);
unbrake((evh) h_accept);

event_dispatch();
twarnx("got here for some reason");
return 0;
}
1 change: 1 addition & 0 deletions conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ conn_close(conn c)

cur_conn_ct--; /* stats */

unbrake(NULL);
conn_remove(c);
conn_free(c);
}
40 changes: 39 additions & 1 deletion net.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
/* net.c - stupid boilerplate shit that I shouldn't have to write */

#include <stdio.h>
#include <errno.h>

#include "net.h"
#include "util.h"

static int listen_socket = -1;
static struct event listen_evq;
static evh accept_handler;

int
make_server_socket(int host, int port)
{
Expand Down Expand Up @@ -38,6 +43,39 @@ make_server_socket(int host, int port)
r = listen(fd, 1024);
if (r == -1) return twarn("listen()"), close(fd), -1;

return fd;
return listen_socket = fd;
}

void
brake()
{
int r;

twarnx("too many connections; putting on the brakes");

r = event_del(&listen_evq);
if (r == -1) twarn("event_del()");

r = listen(listen_socket, 0);
if (r == -1) twarn("listen()");
}

void
unbrake(evh h)
{
int r;

twarnx("releasing the brakes");

accept_handler = h ? : accept_handler;
event_set(&listen_evq, listen_socket, EV_READ | EV_PERSIST,
accept_handler, &listen_evq);

errno = 0;
r = event_add(&listen_evq, NULL);
if (r == -1) twarn("event_add()");

r = listen(listen_socket, 1024);
if (r == -1) twarn("listen()");
}

3 changes: 3 additions & 0 deletions net.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@

int make_server_socket(int host, int port);

void brake();
void unbrake(evh h);

#endif /*net_h*/

0 comments on commit ec812a1

Please sign in to comment.