mirror of https://github.com/omar-polo/gmid.git
gracefully shut down fastcgi backends
we need to delete the events associated with the backends, otherwise the server process won't ever quit. Here, we add a pending counter to every backend and shut down immediately if they aren't handling any client; otherwise we try to close them as soon as possible (i.e. when they close the connection to the last connected client.)
This commit is contained in:
parent
ea976e8743
commit
090b8a89fa
15
fcgi.c
15
fcgi.c
|
@ -381,9 +381,16 @@ close_all(struct fcgi *f)
|
|||
start_reply(c, CGI_ERROR, "CGI error");
|
||||
}
|
||||
|
||||
fcgi_close_backend(f);
|
||||
}
|
||||
|
||||
void
|
||||
fcgi_close_backend(struct fcgi *f)
|
||||
{
|
||||
event_del(&f->e);
|
||||
close(f->fd);
|
||||
f->fd = -1;
|
||||
f->pending = 0;
|
||||
f->s = FCGI_OFF;
|
||||
}
|
||||
|
||||
|
@ -413,6 +420,8 @@ handle_fcgi(int sock, short event, void *d)
|
|||
if (must_read(sock, (char*)&end, sizeof(end)) == -1)
|
||||
goto err;
|
||||
/* TODO: do something with the status? */
|
||||
|
||||
f->pending--;
|
||||
c->fcgi = -1;
|
||||
c->next = close_conn;
|
||||
event_once(c->fd, EV_WRITE, ©_mbuf, c, NULL);
|
||||
|
@ -447,6 +456,10 @@ handle_fcgi(int sock, short event, void *d)
|
|||
|
||||
if (!consume(sock, h.padding))
|
||||
goto err;
|
||||
|
||||
if (f->pending == 0 && shutting_down)
|
||||
fcgi_close_backend(f);
|
||||
|
||||
return;
|
||||
|
||||
err:
|
||||
|
@ -462,6 +475,8 @@ send_fcgi_req(struct fcgi *f, struct client *c)
|
|||
struct tm tminfo;
|
||||
struct envlist *p;
|
||||
|
||||
f->pending++;
|
||||
|
||||
e = getnameinfo((struct sockaddr*)&c->addr, sizeof(c->addr),
|
||||
addr, sizeof(addr),
|
||||
NULL, 0,
|
||||
|
|
1
gmid.c
1
gmid.c
|
@ -333,6 +333,7 @@ free_config(void)
|
|||
fcgi[i].port = NULL;
|
||||
fcgi[i].prog = NULL;
|
||||
|
||||
fcgi[i].pending = 0;
|
||||
fcgi[i].s = FCGI_OFF;
|
||||
}
|
||||
|
||||
|
|
5
gmid.h
5
gmid.h
|
@ -70,6 +70,9 @@ struct fcgi {
|
|||
int fd;
|
||||
struct event e;
|
||||
|
||||
/* number of pending clients */
|
||||
int pending;
|
||||
|
||||
#define FCGI_OFF 0
|
||||
#define FCGI_INFLIGHT 1
|
||||
#define FCGI_READY 2
|
||||
|
@ -337,6 +340,7 @@ void load_default_mime(struct mime*);
|
|||
const char *mime(struct vhost*, const char*);
|
||||
|
||||
/* server.c */
|
||||
extern int shutting_down;
|
||||
const char *vhost_lang(struct vhost*, const char*);
|
||||
const char *vhost_default_mime(struct vhost*, const char*);
|
||||
const char *vhost_index(struct vhost*, const char*);
|
||||
|
@ -375,6 +379,7 @@ int recv_fd(int);
|
|||
int executor_main(struct imsgbuf*);
|
||||
|
||||
/* fcgi.c */
|
||||
void fcgi_close_backend(struct fcgi *);
|
||||
void handle_fcgi(int, short, void*);
|
||||
void send_fcgi_req(struct fcgi*, struct client*);
|
||||
|
||||
|
|
17
server.c
17
server.c
|
@ -26,6 +26,8 @@
|
|||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
int shutting_down;
|
||||
|
||||
struct client clients[MAX_USERS];
|
||||
|
||||
static struct tls *ctx;
|
||||
|
@ -1246,12 +1248,16 @@ handle_imsg_fcgi_fd(struct imsgbuf *ibuf, struct imsg *imsg, size_t len)
|
|||
static void
|
||||
handle_imsg_quit(struct imsgbuf *ibuf, struct imsg *imsg, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
(void)imsg;
|
||||
(void)len;
|
||||
|
||||
/* don't call event_loopbreak since we want to finish to
|
||||
* handle the ongoing connections. */
|
||||
|
||||
shutting_down = 1;
|
||||
|
||||
event_del(&e4);
|
||||
if (has_ipv6)
|
||||
event_del(&e6);
|
||||
|
@ -1259,6 +1265,17 @@ handle_imsg_quit(struct imsgbuf *ibuf, struct imsg *imsg, size_t len)
|
|||
signal_del(&siginfo);
|
||||
event_del(&imsgev);
|
||||
signal_del(&sigusr2);
|
||||
|
||||
for (i = 0; i < FCGI_MAX; ++i) {
|
||||
if (fcgi[i].path == NULL && fcgi[i].prog == NULL)
|
||||
break;
|
||||
|
||||
if (!event_pending(&fcgi[i].e, EV_READ, NULL) ||
|
||||
fcgi[i].pending != 0)
|
||||
continue;
|
||||
|
||||
fcgi_close_backend(&fcgi[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in New Issue