summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjow <jow@3c298f89-4303-0410-b956-a3cf2f4a3e73>2012-07-06 17:29:25 +0000
committerjow <jow@3c298f89-4303-0410-b956-a3cf2f4a3e73>2012-07-06 17:29:25 +0000
commit6b3a770d363bf331306d93dfdf7feacbed0fbb86 (patch)
tree99d14d8e04121d94eb3ed86062d7c31248edcf68
parent0793612583f480c051c9b4c6521a225063c758ab (diff)
downloaduhttpd-6b3a770d363bf331306d93dfdf7feacbed0fbb86.tar.gz
[package] uhttpd: do not subscribe to epoll write events
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. git-svn-id: svn://svn.openwrt.org/openwrt/trunk/package/uhttpd/src@32640 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r--uhttpd-cgi.c1
-rw-r--r--uhttpd-lua.c1
-rw-r--r--uhttpd-utils.c3
-rw-r--r--uhttpd.c23
-rw-r--r--uhttpd.h1
5 files changed, 26 insertions, 3 deletions
diff --git a/uhttpd-cgi.c b/uhttpd-cgi.c
index 8336a1b..aa79478 100644
--- a/uhttpd-cgi.c
+++ b/uhttpd-cgi.c
@@ -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 */
diff --git a/uhttpd-lua.c b/uhttpd-lua.c
index 5158534..10d6de4 100644
--- a/uhttpd-lua.c
+++ b/uhttpd-lua.c
@@ -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 */
diff --git a/uhttpd-utils.c b/uhttpd-utils.c
index dec9523..d31f756 100644
--- a/uhttpd-utils.c
+++ b/uhttpd-utils.c
@@ -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);
diff --git a/uhttpd.c b/uhttpd.c
index d5d5dfb..73f6e03 100644
--- a/uhttpd.c
+++ b/uhttpd.c
@@ -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))
diff --git a/uhttpd.h b/uhttpd.h
index 8fa3f21..69fe21a 100644
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -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 *);