diff options
author | José Bollo <jose.bollo@iot.bzh> | 2016-04-25 16:48:17 +0200 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2016-04-25 16:49:39 +0200 |
commit | 84d141ab55dbc409aed542fe5163f1ed16353beb (patch) | |
tree | 0c3c9b8e8035a5ab5208607f221c76ed3cade3d0 | |
parent | 97c02cb6f98727942bbbdd38b3ecbc1366894ed6 (diff) |
avoid reentering MHD_run
Change-Id: I54547f52c44b05573190cd226f71ee9d40181300
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r-- | src/afb-hsrv.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/src/afb-hsrv.c b/src/afb-hsrv.c index 73ad6a60..abec0ada 100644 --- a/src/afb-hsrv.c +++ b/src/afb-hsrv.c @@ -54,8 +54,15 @@ struct hsrv_alias { int dirfd; }; +enum afb_hsrv_state { + hsrv_idle = 0, + hsrv_run, + hsrv_rerun +}; + struct afb_hsrv { unsigned refcount; + enum afb_hsrv_state state; struct hsrv_handler *handlers; struct MHD_Daemon *httpd; struct upoll *upoll; @@ -203,6 +210,19 @@ static void end_handler(void *cls, struct MHD_Connection *connection, void **rec afb_hreq_free(hreq); } +static void handle_epoll_readable(struct afb_hsrv *hsrv) +{ + if (hsrv->state != hsrv_idle) + hsrv->state = hsrv_rerun; + else { + do { + hsrv->state = hsrv_run; + MHD_run(hsrv->httpd); + } while (hsrv->state == hsrv_rerun); + hsrv->state = hsrv_idle; + } +}; + static int new_client_handler(void *cls, const struct sockaddr *addr, socklen_t addrlen) { return MHD_YES; @@ -347,13 +367,13 @@ int afb_hsrv_start(struct afb_hsrv *hsrv, uint16_t port, unsigned int connection return 0; } - upoll = upoll_open(info->listen_fd, httpd); + upoll = upoll_open(info->listen_fd, hsrv); if (upoll == NULL) { MHD_stop_daemon(httpd); fprintf(stderr, "Error: connection to upoll of httpd failed"); return 0; } - upoll_on_readable(upoll, (void*)MHD_run); + upoll_on_readable(upoll, (void*)handle_epoll_readable); hsrv->httpd = httpd; hsrv->upoll = upoll; |