httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject another misc speedup: three fewer syscalls
Date Sun, 21 Dec 1997 22:25:32 GMT
Just cleaning up my source trees, seeing what patches I've got lying
around that I've never posted...

This is a method of eliminating the SIGUSR1 manipulation during a
request... removing three system calls from the request.  It's only been
lightly tested, but doesn't seem to improve performance that much so I
didn't bother pursuing it.  I mention this on the perf-tuning page when
I'm explaining how to get rid of more syscalls. 

The reason for the complexity is that the accept() needs to be aborted
cleanly -- we cannot have a race condition there at all, if we get a
socket from accept() then we absolutely need to process it.  So we
indirect things such that during accept() a SIGUSR2 will be raised after
the SIGUSR1, and the SIGUSR2 will cause accept() to return EINTR if we
haven't yet received a socket.  Otherwise we'll ignore the SIGUSR2 as well
and continue processing. 

Dean

Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apachen/src/main/http_main.c,v
retrieving revision 1.258
diff -u -r1.258 http_main.c
--- http_main.c	1997/12/21 01:54:39	1.258
+++ http_main.c	1997/12/21 22:07:35
@@ -2053,15 +2053,34 @@
     }
 }
 
-static int volatile usr1_just_die = 1;
+enum usr1_actions {
+    USR1_DEFERRED,
+    USR1_JUST_DIE,
+    USR1_RAISE_USR2
+};
+static enum usr1_actions volatile usr1_action = USR1_JUST_DIE;
 static int volatile deferred_die;
 
 static void usr1_handler(int sig)
 {
-    if (usr1_just_die) {
-	just_die(sig);
-    }
     deferred_die = 1;
+    switch (usr1_action) {
+    case USR1_DEFERRED:
+	break;
+
+    case USR1_JUST_DIE:
+	just_die (sig);
+	break;
+
+    case USR1_RAISE_USR2:
+	raise (SIGUSR2);
+	break;
+    }
+}
+
+static void usr2_handler (int sig)
+{
+    /* nothing to do, we're just causing an EINTR */
 }
 
 /* volatile just in case */
@@ -2798,9 +2817,21 @@
     ap_setjmp(jmpbuffer);
 #ifndef __EMX__
     signal(SIGURG, timeout);
-#endif
-    signal(SIGPIPE, timeout);
+#endif    
+    signal(SIGPIPE, timeout);  
     signal(SIGALRM, alrm_handler);
+    {
+	struct sigaction act;
+
+	act.sa_handler = usr1_handler;
+	sigemptyset(&act.sa_mask);
+	act.sa_flags = SA_RESTART;
+#ifdef  SA_INTERRUPT    /* SunOS */
+	act.sa_flags |= SA_INTERRUPT;
+#endif
+	sigaction(SIGUSR1, &act, NULL);
+    }
+    signal(SIGUSR2, usr2_handler);
 
     while (1) {
 	BUFF *conn_io;
@@ -2810,8 +2841,7 @@
 	 * we can exit cleanly.  Since we're between connections right
 	 * now it's the right time to exit, but we might be blocked in a
 	 * system call when the graceful restart request is made. */
-	usr1_just_die = 1;
-	signal(SIGUSR1, usr1_handler);
+	usr1_action = USR1_JUST_DIE;
 
 	/*
 	 * (Re)initialize this child to a pre-connection state.
@@ -2876,10 +2906,10 @@
 	     * defer the exit
 	     */
 	    deferred_die = 0;
-	    usr1_just_die = 0;
-	    for (;;) {
-		clen = sizeof(sa_client);
-		csd = accept(sd, &sa_client, &clen);
+	    usr1_action = USR1_RAISE_USR2;
+            for (;;) {
+                clen = sizeof(sa_client);
+                csd  = accept(sd, &sa_client, &clen);
 		if (csd >= 0 || errno != EINTR)
 		    break;
 		if (deferred_die) {
@@ -2904,7 +2934,7 @@
 	    }
 
 	    /* go around again, safe to die */
-	    usr1_just_die = 1;
+	    usr1_action = USR1_JUST_DIE;
 	    if (deferred_die) {
 		/* ok maybe not, see ya later */
 		clean_child_exit(0);
@@ -2923,7 +2953,7 @@
 	/* We've got a socket, let's at least process one request off the
 	 * socket before we accept a graceful restart request.
 	 */
-	signal(SIGUSR1, SIG_IGN);
+	usr1_action = USR1_DEFERRED;
 
 	note_cleanups_for_fd(ptrans, csd);
 
@@ -2978,9 +3008,7 @@
 
 	while ((r = read_request(current_conn)) != NULL) {
 
-	    /* read_request_line has already done a
-	     * signal (SIGUSR1, SIG_IGN);
-	     */
+	    usr1_action = USR1_DEFERRED;
 
 	    (void) update_child_status(my_child_num, SERVER_BUSY_WRITE, r);
 
@@ -3016,9 +3044,8 @@
 	     * connections to close before receiving a response because
 	     * of network latencies and server timeouts.
 	     */
-	    usr1_just_die = 1;
-	    signal(SIGUSR1, usr1_handler);
-	}
+	    usr1_action = USR1_RAISE_USR2;
+        }
 
 	/*
 	 * Close the connection, being careful to send out whatever is still
Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apachen/src/main/http_protocol.c,v
retrieving revision 1.171
diff -u -r1.171 http_protocol.c
--- http_protocol.c	1997/12/21 08:18:16	1.171
+++ http_protocol.c	1997/12/21 22:07:37
@@ -709,7 +709,7 @@
         }
     }
     /* we've probably got something to do, ignore graceful restart requests */
-#ifdef SIGUSR1
+#ifdef XXXSIGUSR1
     signal(SIGUSR1, SIG_IGN);
 #endif                          /* SIGUSR1 */
     bsetflag(conn->client, B_SAFEREAD, 0);


Mime
View raw message