[package] uhttpd: do not subscribe to epoll write events
authorJo-Philipp Wich <jow@openwrt.org>
Fri, 6 Jul 2012 17:29:25 +0000 (17:29 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Fri, 6 Jul 2012 17:29:25 +0000 (17:29 +0000)
Watch child read pipe end for data instead of relying on socket write
notification to process cgi data, should lower cpu consumption during
requests on weaker devices.

SVN-Revision: 32640

package/uhttpd/Makefile
package/uhttpd/src/uhttpd-cgi.c
package/uhttpd/src/uhttpd-lua.c
package/uhttpd/src/uhttpd-utils.c
package/uhttpd/src/uhttpd.c
package/uhttpd/src/uhttpd.h

index b8afa0d89f8066591c7959b6301914a952d0f44b..7cd75807ea5e71efa03b7ad2ae0a9a0cc4562362 100644 (file)
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=uhttpd
-PKG_RELEASE:=36
+PKG_RELEASE:=37
 
 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
 PKG_CONFIG_DEPENDS := \
index 8336a1b71f6ecb266f0f7a3cb407613b92bef8e7..aa794781158018bb2adf47f74b6d25097f460d62 100644 (file)
@@ -530,6 +530,7 @@ bool uh_cgi_request(struct client *cl, struct path_info *pi,
                memset(state, 0, sizeof(*state));
 
                state->cl = cl;
+               state->cl->pipe.fd = rfd[0];
                state->cl->proc.pid = child;
 
                /* close unneeded pipe ends */
index 5158534e27103f86a96a70155e0ecb057ba867f1..10d6de402a4d21eee77f992a4aeb81471d5dc6b6 100644 (file)
@@ -558,6 +558,7 @@ bool uh_lua_request(struct client *cl, lua_State *L)
                memset(state, 0, sizeof(*state));
 
                state->cl = cl;
+               state->cl->pipe.fd = rfd[0];
                state->cl->proc.pid = child;
 
                /* close unneeded pipe ends */
index dec952357e4b998a75e5acf788f8c00bb5cb3e45..d31f756d14afea3a29ca0f1384b85228fbaa6e1d 100644 (file)
@@ -996,6 +996,9 @@ void uh_client_remove(struct client *cl)
                        if (cur->proc.pid)
                                uloop_process_delete(&cur->proc);
 
+                       if (cur->pipe.fd)
+                               uloop_fd_delete(&cur->pipe);
+
                        uloop_fd_delete(&cur->fd);
                        close(cur->fd.fd);
 
index d5d5dfb982da4e059fbdc6b9d3ab6c0c9575881d..73f6e03bd47c980dfd1c46db03c288d96f280abb 100644 (file)
@@ -219,7 +219,7 @@ static int uh_socket_bind(fd_set *serv_fds, int *max_fd,
                *max_fd = max(*max_fd, sock);
 
                l->fd.cb = uh_listener_cb;
-               uloop_fd_add(&l->fd, ULOOP_READ | ULOOP_WRITE);
+               uloop_fd_add(&l->fd, ULOOP_READ);
 
                bound++;
                continue;
@@ -539,7 +539,7 @@ static void uh_listener_cb(struct uloop_fd *u, unsigned int events)
                if ((cl = uh_client_add(new_fd, serv)) != NULL)
                {
                        /* add client socket to global fdset */
-                       uloop_fd_add(&cl->fd, ULOOP_READ | ULOOP_WRITE);
+                       uloop_fd_add(&cl->fd, ULOOP_READ);
 
 #ifdef HAVE_TLS
                        /* setup client tls context */
@@ -569,6 +569,15 @@ static void uh_listener_cb(struct uloop_fd *u, unsigned int events)
        }
 }
 
+static void uh_pipe_cb(struct uloop_fd *u, unsigned int events)
+{
+       struct client *cl = container_of(u, struct client, pipe);
+
+       D("SRV: Client(%d) pipe(%d) readable\n", cl->fd.fd, cl->pipe.fd);
+
+       uh_client_cb(&cl->fd, ULOOP_WRITE);
+}
+
 static void uh_child_cb(struct uloop_process *p, int rv)
 {
        struct client *cl = container_of(p, struct client, proc);
@@ -686,6 +695,15 @@ static void uh_client_cb(struct uloop_fd *u, unsigned int events)
                        return;
                }
 
+               /* request handler spawned a pipe, register handler */
+               if (cl->pipe.fd)
+               {
+                       D("SRV: Client(%d) pipe(%d) spawned\n", u->fd, cl->pipe.fd);
+
+                       cl->pipe.cb = uh_pipe_cb;
+                       uloop_fd_add(&cl->pipe, ULOOP_READ);
+               }
+
                /* request handler spawned a child, register handler */
                if (cl->proc.pid)
                {
@@ -701,7 +719,6 @@ static void uh_client_cb(struct uloop_fd *u, unsigned int events)
                /* header processing complete */
                D("SRV: Client(%d) dispatched\n", u->fd);
                cl->dispatched = true;
-               return;
        }
 
        if (!cl->cb(cl))
index 8fa3f219b7e5d270065f5501af00092556a85ed8..69fe21a418824f7f2ffb237b912e7fe61f0c07a9 100644 (file)
@@ -160,6 +160,7 @@ struct client {
        SSL *tls;
 #endif
        struct uloop_fd fd;
+       struct uloop_fd pipe;
        struct uloop_process proc;
        struct uloop_timeout timeout;
        bool (*cb)(struct client *);