aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2012-07-06 17:29:25 +0000
committerJo-Philipp Wich <jow@openwrt.org>2012-07-06 17:29:25 +0000
commit1f2d5da8876fd4475b47093bb566d2eecb87de13 (patch)
tree23791d42fdc6bc4930f598247af965b12d42bf05
parentfe015f399fb6f8ff45b5863f41b8d33f64dfc1bd (diff)
downloadupstream-1f2d5da8876fd4475b47093bb566d2eecb87de13.tar.gz
upstream-1f2d5da8876fd4475b47093bb566d2eecb87de13.tar.bz2
upstream-1f2d5da8876fd4475b47093bb566d2eecb87de13.zip
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.
SVN-Revision: 32640
-rw-r--r--package/uhttpd/Makefile2
-rw-r--r--package/uhttpd/src/uhttpd-cgi.c1
-rw-r--r--package/uhttpd/src/uhttpd-lua.c1
-rw-r--r--package/uhttpd/src/uhttpd-utils.c3
-rw-r--r--package/uhttpd/src/uhttpd.c23
-rw-r--r--package/uhttpd/src/uhttpd.h1
6 files changed, 27 insertions, 4 deletions
diff --git a/package/uhttpd/Makefile b/package/uhttpd/Makefile
index b8afa0d89f..7cd75807ea 100644
--- a/package/uhttpd/Makefile
+++ b/package/uhttpd/Makefile
@@ -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 := \
diff --git a/package/uhttpd/src/uhttpd-cgi.c b/package/uhttpd/src/uhttpd-cgi.c
index 8336a1b71f..aa79478115 100644
--- a/package/uhttpd/src/uhttpd-cgi.c
+++ b/package/uhttpd/src/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/package/uhttpd/src/uhttpd-lua.c b/package/uhttpd/src/uhttpd-lua.c
index 5158534e27..10d6de402a 100644
--- a/package/uhttpd/src/uhttpd-lua.c
+++ b/package/uhttpd/src/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/package/uhttpd/src/uhttpd-utils.c b/package/uhttpd/src/uhttpd-utils.c
index dec952357e..d31f756d14 100644
--- a/package/uhttpd/src/uhttpd-utils.c
+++ b/package/uhttpd/src/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/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c
index d5d5dfb982..73f6e03bd4 100644
--- a/package/uhttpd/src/uhttpd.c
+++ b/package/uhttpd/src/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/package/uhttpd/src/uhttpd.h b/package/uhttpd/src/uhttpd.h
index 8fa3f219b7..69fe21a418 100644
--- a/package/uhttpd/src/uhttpd.h
+++ b/package/uhttpd/src/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 *);