Commit Diff


commit - cfb8a77fd4e7addd5486d68419bb44fd80b63e3b
commit + a709ddf5eb71e90a66cfd02bdaa9116c7f7ec3d6
blob - 8c067118f80a6563f880bce832a463c7c3d395dd
blob + bf662e37bc7aecfb660fa7d68f1c2d5885361f33
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,7 @@
+2021-02-07  Omar Polo  <op@omarpolo.com>
+
+	* parse.y (option): added prefork option
+
 2021-02-06  Omar Polo  <op@omarpolo.com>
 
 	* parse.y (locopt): added ``block return'' and ``strip'' options
blob - a7179efedf36ce0f2d3b63b40feeca7a4fbe02a7
blob + b2938f9fda6e1f4d8dd0c3a61980bf6f48d0cafb
--- gmid.1
+++ gmid.1
@@ -150,6 +150,12 @@ Both argument are strings.
 .It Ic port Ar portno
 The port to listen on.
 By default is 1965.
+.It Ic prefork Ar number
+Run the specified number of server processes.
+This increases the performance and prevents delays when connecting to
+a server.
+.Nm
+runs 3 server processes by default, when not in config-less mode.
 .It Ic protocols Ar string
 Specify the TLS protocols to enable.
 Refer to
blob - 8a9a52b65387862993e6fdcad3f98ec9eae63b08
blob + a4f7868371625d6f8e6bbbb98ad75617eecace5d
--- gmid.c
+++ gmid.c
@@ -391,6 +391,8 @@ setup_tls(void)
 static int
 listener_main(void)
 {
+	drop_priv();
+	unblock_signals();
 	load_default_mime(&conf.mime);
 	load_vhosts();
 	sandbox();
@@ -415,6 +417,9 @@ init_config(void)
 
 	conf.chroot = NULL;
 	conf.user = NULL;
+
+	/* we'll change this to 0 when running without config. */
+	conf.prefork = 3;
 }
 
 void
@@ -496,6 +501,31 @@ usage(const char *me)
 	    "USAGE: %s [-fn] [-c config] | [-6h] [-d certs-dir] [-H host]"
 	    "       [-p port] [-x cgi] [dir]",
 	    me);
+}
+
+static int
+spawn_listeners(int *p)
+{
+	int i;
+
+	close(p[0]);
+	exfd = p[1];
+
+	for (i = 0; i < conf.prefork -1; ++i) {
+		switch (fork()) {
+		case -1:
+			fatal("fork: %s", strerror(errno));
+		case 0:		/* child */
+			setproctitle("server(%d)", i+1);
+			return listener_main();
+		}
+	}
+
+	if (conf.prefork == 0)
+		setproctitle("server");
+	else
+		setproctitle("server(%d)", conf.prefork);
+	return listener_main();
 }
 
 static int
@@ -538,13 +568,7 @@ serve(int argc, char **argv, int *p)
 		fatal("fork: %s", strerror(errno));
 
 	case 0:			/* child */
-		setproctitle("listener");
-		close(p[0]);
-		exfd = p[1];
-		drop_priv();
-		unblock_signals();
-		listener_main();
-		_exit(0);
+		return spawn_listeners(p);
 
 	default:		/* parent */
 		setproctitle("executor");
@@ -663,8 +687,10 @@ main(int argc, char **argv)
 	if (conf.ipv6)
 		sock6 = make_socket(conf.port, AF_INET6);
 
-	if (configless)
+	if (configless) {
+		conf.prefork = 0;
 		return serve(argc, argv, p);
+	}
 
 	/* wait a sighup and reload the daemon */
 	for (;;) {
blob - 1701c98cdd2dc08328f952a0814f05bac533d295
blob + 51379fb849613a40b3ec715d74a73ad41908880f
--- gmid.h
+++ gmid.h
@@ -109,6 +109,7 @@ struct conf {
 	struct mime	 mime;
 	char		*chroot;
 	char		*user;
+	int		 prefork;
 };
 
 extern struct conf conf;
blob - 8f233fbf8519b8205280cbca06e5098ccd387a91
blob + abfced4b7cf6eb8c4dde49c5c6d69a5fb3bdc489
--- lex.l
+++ lex.l
@@ -60,6 +60,7 @@ type		return TTYPE;
 chroot		return TCHROOT;
 user		return TUSER;
 server		return TSERVER;
+prefork		return TPREFORK;
 
 location	return TLOCATION;
 cert		return TCERT;
blob - 000ba0bd8034e00b388d8cf6639f928b58311c60
blob + 267eb593d480b2d84607b5e8ea0b1b54ac73a9ee
--- parse.y
+++ parse.y
@@ -44,6 +44,7 @@ char		*ensure_absolute_path(char*);
 int		 check_block_code(int);
 char		*check_block_fmt(char*);
 int		 check_strip_no(int);
+int		 check_prefork_num(int);
 
 %}
 
@@ -56,7 +57,7 @@ int		 check_strip_no(int);
 }
 
 %token TIPV6 TPORT TPROTOCOLS TMIME TDEFAULT TTYPE
-%token TCHROOT TUSER TSERVER
+%token TCHROOT TUSER TSERVER TPREFORK
 %token TLOCATION TCERT TKEY TROOT TCGI TLANG TINDEX TAUTO
 %token TSTRIP TBLOCK TRETURN TENTRYPOINT
 %token TERR
@@ -82,6 +83,7 @@ option		: TIPV6 TBOOL		{ conf.ipv6 = $2; }
 		| TMIME TSTRING TSTRING	{ add_mime(&conf.mime, $2, $3); }
 		| TCHROOT TSTRING	{ conf.chroot = $2; }
 		| TUSER TSTRING		{ conf.user = $2; }
+		| TPREFORK TNUM		{ conf.prefork = check_prefork_num($2); }
 		;
 
 vhosts		: /* empty */
@@ -280,5 +282,13 @@ check_strip_no(int n)
 {
 	if (n <= 0)
 		yyerror("invalid strip number %d", n);
+	return n;
+}
+
+int
+check_prefork_num(int n)
+{
+	if (n <= 0)
+		yyerror("invalid prefork number %d", n);
 	return n;
 }