aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2016-04-25 16:48:17 +0200
committerJosé Bollo <jose.bollo@iot.bzh>2016-04-25 16:49:39 +0200
commit84d141ab55dbc409aed542fe5163f1ed16353beb (patch)
tree0c3c9b8e8035a5ab5208607f221c76ed3cade3d0
parent97c02cb6f98727942bbbdd38b3ecbc1366894ed6 (diff)
avoid reentering MHD_run
Change-Id: I54547f52c44b05573190cd226f71ee9d40181300 Signed-off-by: José Bollo <jose.bollo@iot.bzh>
-rw-r--r--src/afb-hsrv.c24
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;