Commit Diff


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, &copy_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 <fnmatch.h>
 #include <limits.h>
 #include <string.h>
+
+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