commit 090b8a89faa34cdc41c41e32845f1f5b444536e4 from: Omar Polo date: Tue Jul 06 10:54:27 2021 UTC 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.) commit - ea976e8743ad3b3263faae00d88e40bcf727097d commit + 090b8a89faa34cdc41c41e32845f1f5b444536e4 blob - fbe07cedb7375f92973537d5675b7aad4e67b25c blob + 3facd2d335d90c667df13ac31b745032942f2569 --- fcgi.c +++ 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, blob - 224eb4270ee4159606fc1ee3e31d30765a8eff9e blob + 8a2a9401ac5517b38c92199114a0d13d64f3774c --- gmid.c +++ 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; } blob - 26ad06c3df63f7fd26eb40b970f28d4785fee7cf blob + 320cabf2b5c04db2b1e72c28aafed9a1fd59f802 --- gmid.h +++ 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*); blob - d07a6429b6cf960bdfd62628fd00466c3eebe03b blob + 93e5ffd04e147345de4bb1751b1629a24be112e3 --- server.c +++ server.c @@ -25,6 +25,8 @@ #include #include #include + +int shutting_down; struct client clients[MAX_USERS]; @@ -1246,12 +1248,16 @@ handle_imsg_fcgi_fd(struct imsgbuf *ibuf, struct imsg 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 *im 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