diff options
author | Felix Fietkau <nbd@openwrt.org> | 2013-05-23 12:41:03 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2013-05-23 12:41:52 +0200 |
commit | d58f77ad52caa52e91cf698e60a5a43c5d870e84 (patch) | |
tree | 385d87092fe45e8c0b68595becb095cfd13f8fc2 | |
parent | 692cb27c49f9c543aef8f25f8c270a27ddec2a74 (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.c | 17 | ||||
-rw-r--r-- | uhttpd.h | 1 |
2 files changed, 13 insertions, 5 deletions
@@ -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; } @@ -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; |