summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2013-05-23 12:41:03 +0200
committerFelix Fietkau <nbd@openwrt.org>2013-05-23 12:41:52 +0200
commitd58f77ad52caa52e91cf698e60a5a43c5d870e84 (patch)
tree385d87092fe45e8c0b68595becb095cfd13f8fc2
parent692cb27c49f9c543aef8f25f8c270a27ddec2a74 (diff)
relay: fix close handling
When the relay process has exited, close the connection as soon as no data can immediately be read from the socket anymore, and the read buffer has been emptied. This fixes timeouts with scripts that leave processes lingering around without closing their fds. Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-rw-r--r--relay.c17
-rw-r--r--uhttpd.h1
2 files changed, 13 insertions, 5 deletions
diff --git a/relay.c b/relay.c
index 83664e6..1b55d41 100644
--- a/relay.c
+++ b/relay.c
@@ -115,6 +115,9 @@ static void relay_read_cb(struct ustream *s, int bytes)
char *buf;
int len;
+ if (r->process_done)
+ uloop_timeout_set(&r->timeout, 1);
+
relay_process_headers(r);
if (r->header_cb) {
@@ -140,11 +143,14 @@ static void relay_read_cb(struct ustream *s, int bytes)
ustream_consume(s, len);
}
-static void relay_close_if_done(struct relay *r)
+static void relay_close_if_done(struct uloop_timeout *timeout)
{
+ struct relay *r = container_of(timeout, struct relay, timeout);
struct ustream *s = &r->sfd.stream;
- if (!s->eof || ustream_pending_data(s, false))
+ while (ustream_poll(&r->sfd.stream));
+
+ if (!(r->process_done || s->eof) || ustream_pending_data(s, false))
return;
uh_relay_close(r, r->ret);
@@ -155,17 +161,16 @@ static void relay_state_cb(struct ustream *s)
struct relay *r = container_of(s, struct relay, sfd.stream);
if (r->process_done)
- relay_close_if_done(r);
+ uloop_timeout_set(&r->timeout, 1);
}
static void relay_proc_cb(struct uloop_process *proc, int ret)
{
struct relay *r = container_of(proc, struct relay, proc);
- ustream_poll(&r->sfd.stream);
r->process_done = true;
r->ret = ret;
- relay_close_if_done(r);
+ uloop_timeout_set(&r->timeout, 1);
}
void uh_relay_kill(struct client *cl, struct relay *r)
@@ -190,4 +195,6 @@ void uh_relay_open(struct client *cl, struct relay *r, int fd, int pid)
r->proc.pid = pid;
r->proc.cb = relay_proc_cb;
uloop_process_add(&r->proc);
+
+ r->timeout.cb = relay_close_if_done;
}
diff --git a/uhttpd.h b/uhttpd.h
index d6b6985..59f1565 100644
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -146,6 +146,7 @@ struct env_var {
struct relay {
struct ustream_fd sfd;
struct uloop_process proc;
+ struct uloop_timeout timeout;
struct client *cl;
bool process_done;