diff --git a/src/dumpstats.c b/src/dumpstats.c index 0a2bd6747..809025f2b 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -2428,14 +2428,14 @@ static void cli_io_handler(struct appctx *appctx) res->flags |= CF_READ_NULL; } + out: /* update all other flags and resync with the other side */ - si_update(si); + si_applet_done(si); /* we don't want to expire timeouts while we're processing requests */ si_ic(si)->rex = TICK_ETERNITY; si_oc(si)->wex = TICK_ETERNITY; - out: DPRINTF(stderr, "%s@%d: st=%d, rqf=%x, rpf=%x, rqh=%d, rqs=%d, rh=%d, rs=%d\n", __FUNCTION__, __LINE__, si->state, req->flags, res->flags, req->buf->i, req->buf->o, res->buf->i, res->buf->o); @@ -4897,7 +4897,7 @@ static void http_stats_io_handler(struct appctx *appctx) if (bi_putchk(si_ic(si), &trash) == -1) { si->flags |= SI_FL_WAIT_ROOM; si_ic(si)->to_forward = last_fwd; - goto fail; + goto out; } } @@ -4948,7 +4948,7 @@ static void http_stats_io_handler(struct appctx *appctx) chunk_printf(&trash, "\r\n0\r\n\r\n"); if (bi_putchk(si_ic(si), &trash) == -1) { si->flags |= SI_FL_WAIT_ROOM; - goto fail; + goto out; } } /* eat the whole request */ @@ -4967,15 +4967,14 @@ static void http_stats_io_handler(struct appctx *appctx) } } - fail: + out: /* update all other flags and resync with the other side */ - si_update(si); + si_applet_done(si); /* we don't want to expire timeouts while we're processing requests */ si_ic(si)->rex = TICK_ETERNITY; si_oc(si)->wex = TICK_ETERNITY; - out: if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO)) { /* check that we have released everything then unregister */ stream_int_unregister_handler(si); diff --git a/src/hlua.c b/src/hlua.c index 68f0a3928..fb006e6e1 100644 --- a/src/hlua.c +++ b/src/hlua.c @@ -1446,11 +1446,11 @@ static void hlua_socket_handler(struct appctx *appctx) si_ic(si)->flags |= CF_READ_NULL; hlua_com_wake(&appctx->ctx.hlua.wake_on_read); hlua_com_wake(&appctx->ctx.hlua.wake_on_write); - return; + goto leave; } if (!(c->flags & CO_FL_CONNECTED)) - return; + goto leave; /* This function is called after the connect. */ appctx->ctx.hlua.connected = 1; @@ -1462,6 +1462,9 @@ static void hlua_socket_handler(struct appctx *appctx) /* Wake the tasks which wants to read if the buffer contains data. */ if (channel_is_empty(si_ic(si))) hlua_com_wake(&appctx->ctx.hlua.wake_on_read); + + leave: + si_applet_done(si); } /* This function is called when the "struct stream" is destroyed. @@ -1631,7 +1634,7 @@ __LJMP static int hlua_socket_receive_yield(struct lua_State *L, int status, lua bo_skip(oc, len + skip_at_end); /* Don't wait anything. */ - si_update(&socket->s->si[0]); + si_applet_done(&socket->s->si[0]); /* If the pattern reclaim to read all the data * in the connection, got out. @@ -1808,7 +1811,7 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext } /* update buffers. */ - si_update(&socket->s->si[0]); + si_applet_done(&socket->s->si[0]); socket->s->req.rex = TICK_ETERNITY; socket->s->res.wex = TICK_ETERNITY; diff --git a/src/peers.c b/src/peers.c index 2a927e0da..97a87289d 100644 --- a/src/peers.c +++ b/src/peers.c @@ -1038,17 +1038,16 @@ incomplete: si_shutw(si); si_shutr(si); si_ic(si)->flags |= CF_READ_NULL; - goto quit; + goto out; } } } out: - si_update(si); + si_applet_done(si); si_oc(si)->flags |= CF_READ_DONTWAIT; /* we don't want to expire timeouts while we're processing requests */ si_ic(si)->rex = TICK_ETERNITY; si_oc(si)->wex = TICK_ETERNITY; -quit: return; full: si->flags |= SI_FL_WAIT_ROOM; diff --git a/src/stream_interface.c b/src/stream_interface.c index 37dad7ec0..2fdd94f6b 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -394,6 +394,7 @@ struct appctx *stream_int_register_handler(struct stream_interface *si, struct a return NULL; si->flags |= SI_FL_WAIT_DATA; + appctx_wakeup(appctx); return si_appctx(si); } @@ -1569,6 +1570,8 @@ static void stream_int_shutr_applet(struct stream_interface *si) ic->rex = TICK_ETERNITY; si->flags &= ~SI_FL_WAIT_ROOM; + /* Note: on shutr, we don't call the applet */ + if (si->state != SI_ST_EST && si->state != SI_ST_CON) return; @@ -1581,10 +1584,6 @@ static void stream_int_shutr_applet(struct stream_interface *si) /* we want to immediately forward this close to the write side */ return stream_int_shutw_applet(si); } - - /* note that if the task exists, it must unregister itself once it runs */ - if (!(si->flags & SI_FL_DONT_WAKE)) - task_wakeup(si_task(si), TASK_WOKEN_IO); } /* @@ -1606,6 +1605,9 @@ static void stream_int_shutw_applet(struct stream_interface *si) oc->wex = TICK_ETERNITY; si->flags &= ~SI_FL_WAIT_DATA; + /* on shutw we always wake the applet up */ + appctx_wakeup(si_appctx(si)); + switch (si->state) { case SI_ST_EST: /* we have to shut before closing, otherwise some short messages @@ -1633,10 +1635,6 @@ static void stream_int_shutw_applet(struct stream_interface *si) ic->rex = TICK_ETERNITY; si->exp = TICK_ETERNITY; } - - /* note that if the task exists, it must unregister itself once it runs */ - if (!(si->flags & SI_FL_DONT_WAKE)) - task_wakeup(si_task(si), TASK_WOKEN_IO); } /* chk_rcv function for applets */ @@ -1650,17 +1648,14 @@ static void stream_int_chk_rcv_applet(struct stream_interface *si) if (unlikely(si->state != SI_ST_EST || (ic->flags & (CF_SHUTR|CF_DONT_READ)))) return; + /* here we only wake the applet up if it was waiting for some room */ + if (!(si->flags & SI_FL_WAIT_ROOM)) + return; - if (!channel_may_recv(ic) || ic->pipe) { - /* stop reading */ - si->flags |= SI_FL_WAIT_ROOM; - } - else { + if (channel_may_recv(ic) && !ic->pipe) { /* (re)start reading */ - si->flags &= ~SI_FL_WAIT_ROOM; - if (!(si->flags & SI_FL_DONT_WAKE)) - task_wakeup(si_task(si), TASK_WOKEN_IO); - } + appctx_wakeup(si_appctx(si)); + } } /* chk_snd function for applets */ @@ -1675,19 +1670,18 @@ static void stream_int_chk_snd_applet(struct stream_interface *si) if (unlikely(si->state != SI_ST_EST || (oc->flags & CF_SHUTW))) return; - if (!(si->flags & SI_FL_WAIT_DATA) || /* not waiting for data */ - channel_is_empty(oc)) /* called with nothing to send ! */ + /* we only wake the applet up if it was waiting for some data */ + + if (!(si->flags & SI_FL_WAIT_DATA)) return; - /* Otherwise there are remaining data to be sent in the buffer, - * so we tell the handler. - */ - si->flags &= ~SI_FL_WAIT_DATA; if (!tick_isset(oc->wex)) oc->wex = tick_add_ifset(now_ms, oc->wto); - if (!(si->flags & SI_FL_DONT_WAKE)) - task_wakeup(si_task(si), TASK_WOKEN_IO); + if (!channel_is_empty(oc)) { + /* (re)start sending */ + appctx_wakeup(si_appctx(si)); + } } /*