]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: applet: make the applets only use si_applet_{cant|want|stop}_{get|put}
authorWilly Tarreau <w@1wt.eu>
Tue, 21 Apr 2015 17:23:39 +0000 (19:23 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 23 Apr 2015 15:56:17 +0000 (17:56 +0200)
The applets don't fiddle with SI_FL_WAIT_ROOM anymore, instead they indicate
what they want, possibly that they failed (eg: WAIT_ROOM), and it's done() /
update() which finally updates the WAIT_* flags according to the channels'
and stream interface's states. This solves the issue of the pauses during a
"show sess" without creating busy loops.

src/applet.c
src/dumpstats.c
src/peers.c
src/stream.c
src/stream_interface.c

index 37303f7447333496b6cfd228b06c5c897bcc80ee..481000a80b4296896ab9239580e9e83fb994b3bf 100644 (file)
@@ -37,6 +37,13 @@ void applet_run_active()
                        continue;
                }
 
+               /* We always pretend the applet can't get and doesn't want to
+                * put, it's up to it to change this if needed. This ensures
+                * that one applet which ignores any event will not spin.
+                */
+               si_applet_cant_get(si);
+               si_applet_stop_put(si);
+
                curr->applet->fct(curr);
                si_applet_done(si);
        }
index c835b1eb98fd4a0fb1e3b64d9e18d8e44293c10b..b8e822ff52332c6a8a0e3af395c1b8ca7132b2a3 100644 (file)
@@ -557,7 +557,7 @@ static int stats_dump_table_head_to_buffer(struct chunk *msg, struct stream_inte
                chunk_appendf(msg, "# contents not dumped due to insufficient privileges\n");
 
        if (bi_putchk(si_ic(si), msg) == -1) {
-               si->flags |= SI_FL_WAIT_ROOM;
+               si_applet_cant_put(si);
                return 0;
        }
 
@@ -630,7 +630,7 @@ static int stats_dump_table_entry_to_buffer(struct chunk *msg, struct stream_int
        chunk_appendf(msg, "\n");
 
        if (bi_putchk(si_ic(si), msg) == -1) {
-               si->flags |= SI_FL_WAIT_ROOM;
+               si_applet_cant_put(si);
                return 0;
        }
 
@@ -1311,7 +1311,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
                        /* return server's effective weight at the moment */
                        snprintf(trash.str, trash.size, "%d (initial %d)\n", sv->uweight, sv->iweight);
                        if (bi_putstr(si_ic(si), trash.str) == -1)
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
 
                        return 1;
                }
@@ -2247,7 +2247,7 @@ static void cli_io_handler(struct appctx *appctx)
                         * would want to return some info right after parsing.
                         */
                        if (buffer_almost_full(si_ib(si))) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                break;
                        }
 
@@ -2326,7 +2326,7 @@ static void cli_io_handler(struct appctx *appctx)
                                if (bi_putstr(si_ic(si), appctx->ctx.cli.msg) != -1)
                                        appctx->st0 = STAT_CLI_PROMPT;
                                else
-                                       si->flags |= SI_FL_WAIT_ROOM;
+                                       si_applet_cant_put(si);
                                break;
                        case STAT_CLI_PRINT_FREE:
                                if (bi_putstr(si_ic(si), appctx->ctx.cli.err) != -1) {
@@ -2334,7 +2334,7 @@ static void cli_io_handler(struct appctx *appctx)
                                        appctx->st0 = STAT_CLI_PROMPT;
                                }
                                else
-                                       si->flags |= SI_FL_WAIT_ROOM;
+                                       si_applet_cant_put(si);
                                break;
                        case STAT_CLI_O_INFO:
                                if (stats_dump_info_to_buffer(si))
@@ -2384,7 +2384,7 @@ static void cli_io_handler(struct appctx *appctx)
                                if (bi_putstr(si_ic(si), appctx->st1 ? "\n> " : "\n") != -1)
                                        appctx->st0 = STAT_CLI_GETREQ;
                                else
-                                       si->flags |= SI_FL_WAIT_ROOM;
+                                       si_applet_cant_put(si);
                        }
 
                        /* If the output functions are still there, it means they require more room. */
@@ -2541,7 +2541,7 @@ static int stats_dump_info_to_buffer(struct stream_interface *si)
                     );
 
        if (bi_putchk(si_ic(si), &trash) == -1) {
-               si->flags |= SI_FL_WAIT_ROOM;
+               si_applet_cant_put(si);
                return 0;
        }
 
@@ -2556,7 +2556,7 @@ static int stats_dump_pools_to_buffer(struct stream_interface *si)
 {
        dump_pools_to_trash();
        if (bi_putchk(si_ic(si), &trash) == -1) {
-               si->flags |= SI_FL_WAIT_ROOM;
+               si_applet_cant_put(si);
                return 0;
        }
        return 1;
@@ -3809,7 +3809,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy
                if (appctx->ctx.stats.flags & STAT_FMT_HTML) {
                        stats_dump_html_px_hdr(si, px, uri);
                        if (bi_putchk(rep, &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
                }
@@ -3821,7 +3821,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy
                /* print the frontend */
                if (stats_dump_fe_stats(si, px)) {
                        if (bi_putchk(rep, &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
                }
@@ -3834,7 +3834,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy
                /* stats.l has been initialized above */
                for (; appctx->ctx.stats.l != &px->conf.listeners; appctx->ctx.stats.l = l->by_fe.n) {
                        if (buffer_almost_full(rep->buf)) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
 
@@ -3853,7 +3853,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy
                        /* print the frontend */
                        if (stats_dump_li_stats(si, px, l, uri ? uri->flags : 0)) {
                                if (bi_putchk(rep, &trash) == -1) {
-                                       si->flags |= SI_FL_WAIT_ROOM;
+                                       si_applet_cant_put(si);
                                        return 0;
                                }
                        }
@@ -3870,7 +3870,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy
                        enum srv_stats_colour sv_colour;
 
                        if (buffer_almost_full(rep->buf)) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
 
@@ -3949,7 +3949,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy
 
                        if (stats_dump_sv_stats(si, px, uri ? uri->flags : 0, sv, sv_state, sv_colour)) {
                                if (bi_putchk(rep, &trash) == -1) {
-                                       si->flags |= SI_FL_WAIT_ROOM;
+                                       si_applet_cant_put(si);
                                        return 0;
                                }
                        }
@@ -3962,7 +3962,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy
                /* print the backend */
                if (stats_dump_be_stats(si, px, uri ? uri->flags : 0)) {
                        if (bi_putchk(rep, &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
                }
@@ -3974,7 +3974,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy
                if (appctx->ctx.stats.flags & STAT_FMT_HTML) {
                        stats_dump_html_px_end(si, px);
                        if (bi_putchk(rep, &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
                }
@@ -4367,7 +4367,7 @@ static int stats_dump_stat_to_buffer(struct stream_interface *si, struct uri_aut
                        stats_dump_csv_header();
 
                if (bi_putchk(rep, &trash) == -1) {
-                       si->flags |= SI_FL_WAIT_ROOM;
+                       si_applet_cant_put(si);
                        return 0;
                }
 
@@ -4378,7 +4378,7 @@ static int stats_dump_stat_to_buffer(struct stream_interface *si, struct uri_aut
                if (appctx->ctx.stats.flags & STAT_FMT_HTML) {
                        stats_dump_html_info(si, uri);
                        if (bi_putchk(rep, &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
                }
@@ -4392,7 +4392,7 @@ static int stats_dump_stat_to_buffer(struct stream_interface *si, struct uri_aut
                /* dump proxies */
                while (appctx->ctx.stats.px) {
                        if (buffer_almost_full(rep->buf)) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
 
@@ -4414,7 +4414,7 @@ static int stats_dump_stat_to_buffer(struct stream_interface *si, struct uri_aut
                if (appctx->ctx.stats.flags & STAT_FMT_HTML) {
                        stats_dump_html_end();
                        if (bi_putchk(rep, &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
                }
@@ -4784,7 +4784,7 @@ static int stats_send_http_headers(struct stream_interface *si)
        s->logs.tv_request = now;
 
        if (bi_putchk(si_ic(si), &trash) == -1) {
-               si->flags |= SI_FL_WAIT_ROOM;
+               si_applet_cant_put(si);
                return 0;
        }
 
@@ -4831,7 +4831,7 @@ static int stats_send_http_redirect(struct stream_interface *si)
        s->logs.tv_request = now;
 
        if (bi_putchk(si_ic(si), &trash) == -1) {
-               si->flags |= SI_FL_WAIT_ROOM;
+               si_applet_cant_put(si);
                return 0;
        }
 
@@ -4883,7 +4883,7 @@ static void http_stats_io_handler(struct appctx *appctx)
                        si_ic(si)->to_forward = 0;
                        chunk_printf(&trash, "\r\n000000\r\n");
                        if (bi_putchk(si_ic(si), &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                si_ic(si)->to_forward = last_fwd;
                                goto out;
                        }
@@ -4909,7 +4909,7 @@ static void http_stats_io_handler(struct appctx *appctx)
                        if (last_len != data_len) {
                                chunk_printf(&trash, "\r\n%06x\r\n", (last_len - data_len));
                                if (bi_putchk(si_ic(si), &trash) == -1)
-                                       si->flags |= SI_FL_WAIT_ROOM;
+                                       si_applet_cant_put(si);
 
                                si_ic(si)->total += (last_len - data_len);
                                si_ib(si)->i     += (last_len - data_len);
@@ -4935,7 +4935,7 @@ static void http_stats_io_handler(struct appctx *appctx)
                if (appctx->ctx.stats.flags & STAT_CHUNKED) {
                        chunk_printf(&trash, "\r\n0\r\n\r\n");
                        if (bi_putchk(si_ic(si), &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                goto out;
                        }
                }
@@ -5024,7 +5024,7 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si, struct st
                /* stream changed, no need to go any further */
                chunk_appendf(&trash, "  *** session terminated while we were watching it ***\n");
                if (bi_putchk(si_ic(si), &trash) == -1) {
-                       si->flags |= SI_FL_WAIT_ROOM;
+                       si_applet_cant_put(si);
                        return 0;
                }
                appctx->ctx.sess.uid = 0;
@@ -5307,7 +5307,7 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si, struct st
                             sess->res.buf->size);
 
                if (bi_putchk(si_ic(si), &trash) == -1) {
-                       si->flags |= SI_FL_WAIT_ROOM;
+                       si_applet_cant_put(si);
                        return 0;
                }
 
@@ -5332,7 +5332,7 @@ static int stats_pats_list(struct stream_interface *si)
                chunk_reset(&trash);
                chunk_appendf(&trash, "# id (file) description\n");
                if (bi_putchk(si_ic(si), &trash) == -1) {
-                       si->flags |= SI_FL_WAIT_ROOM;
+                       si_applet_cant_put(si);
                        return 0;
                }
 
@@ -5362,7 +5362,7 @@ static int stats_pats_list(struct stream_interface *si)
                                /* let's try again later from this stream. We add ourselves into
                                 * this stream's users so that it can remove us upon termination.
                                 */
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
 
@@ -5481,7 +5481,7 @@ static int stats_map_lookup(struct stream_interface *si)
                                /* let's try again later from this stream. We add ourselves into
                                 * this stream's users so that it can remove us upon termination.
                                 */
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
 
@@ -5532,7 +5532,7 @@ static int stats_pat_list(struct stream_interface *si)
                                /* let's try again later from this stream. We add ourselves into
                                 * this stream's users so that it can remove us upon termination.
                                 */
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
 
@@ -5737,7 +5737,7 @@ static int stats_dump_sess_to_buffer(struct stream_interface *si)
                                /* let's try again later from this stream. We add ourselves into
                                 * this stream's users so that it can remove us upon termination.
                                 */
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                LIST_ADDQ(&curr_sess->back_refs, &appctx->ctx.sess.bref.users);
                                return 0;
                        }
@@ -5754,7 +5754,7 @@ static int stats_dump_sess_to_buffer(struct stream_interface *si)
                                chunk_appendf(&trash, "Session not found.\n");
 
                        if (bi_putchk(si_ic(si), &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
 
@@ -6035,7 +6035,7 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si)
 
                if (bi_putchk(si_ic(si), &trash) == -1) {
                        /* Socket buffer full. Let's try again later from the same point */
-                       si->flags |= SI_FL_WAIT_ROOM;
+                       si_applet_cant_put(si);
                        return 0;
                }
 
@@ -6120,7 +6120,7 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si)
 
                        if (bi_putchk(si_ic(si), &trash) == -1) {
                                /* Socket buffer full. Let's try again later from the same point */
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
                        appctx->ctx.errors.ptr = 0;
@@ -6132,7 +6132,7 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si)
                        chunk_appendf(&trash,
                                     "  WARNING! update detected on this snapshot, dump interrupted. Please re-check!\n");
                        if (bi_putchk(si_ic(si), &trash) == -1) {
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
                        goto next;
@@ -6150,7 +6150,7 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si)
 
                        if (bi_putchk(si_ic(si), &trash) == -1) {
                                /* Socket buffer full. Let's try again later from the same point */
-                               si->flags |= SI_FL_WAIT_ROOM;
+                               si_applet_cant_put(si);
                                return 0;
                        }
                        appctx->ctx.errors.ptr = newptr;
index 5b6d817861e46fff2b07e23c45899962d2eaef86..26b3e6fde220cec01684a82df492df88d87fae6c 100644 (file)
@@ -1046,7 +1046,7 @@ out:
        si_oc(si)->flags |= CF_READ_DONTWAIT;
        return;
 full:
-       si->flags |= SI_FL_WAIT_ROOM;
+       si_applet_cant_put(si);
        goto out;
 }
 
index 77a67b808160ab10cc9d4b36fedcf270a8b1f614..12b6f9db81ba1cb10b92a283c7b301c1e55f165f 100644 (file)
@@ -200,7 +200,7 @@ struct stream *stream_new(struct session *sess, struct task *t, enum obj_type *o
        if (conn)
                conn_data_want_recv(conn);
        else if (appctx)
-               s->si[0].flags |= SI_FL_WAIT_DATA;
+               si_applet_want_get(&s->si[0]);
 
        if (sess->fe->accept && sess->fe->accept(s) < 0)
                goto out_fail_accept;
index 55f0e221195201e0a96b749a38c02c945c42b091..08946dfdf8ddffe5f4879614e9ea26f374225003 100644 (file)
@@ -393,7 +393,7 @@ struct appctx *stream_int_register_handler(struct stream_interface *si, struct a
        if (!appctx)
                return NULL;
 
-       si->flags |= SI_FL_WAIT_DATA;
+       si_applet_cant_get(si);
        appctx_wakeup(appctx);
        return si_appctx(si);
 }
@@ -1433,14 +1433,9 @@ void si_applet_done(struct stream_interface *si)
                        ic->rex = tick_add_ifset(now_ms, ic->rto);
        }
 
-       /* get away from the active list if we can't work anymore, that is
-        * we're blocked both for reads or writes or once both sides are closed.
-        * FIXME: we may have a problem here with bidirectional applets which
-        * might block on a single direction while the other one is still free.
-        */
-       if ((si->flags & (SI_FL_WAIT_ROOM|SI_FL_WAIT_DATA)) ||
-           (ic->flags & CF_DONT_READ) ||
-           (ic->flags & CF_SHUTR && oc->flags & CF_SHUTW))
+       /* get away from the active list if we can't work anymore. */
+       if (((si->flags & (SI_FL_WANT_PUT|SI_FL_WAIT_ROOM)) != SI_FL_WANT_PUT) &&
+           ((si->flags & (SI_FL_WANT_GET|SI_FL_WAIT_DATA)) != SI_FL_WANT_GET))
                appctx_pause(si_appctx(si));
 
        /* wake the task up only when needed */
@@ -1531,10 +1526,11 @@ void stream_int_update_applet(struct stream_interface *si)
                }
        }
 
-       if (!(si->flags & (SI_FL_WAIT_ROOM|SI_FL_WAIT_DATA)) &&
-           !(ic->flags & CF_DONT_READ) &&
-           (!(ic->flags & CF_SHUTR) || !(oc->flags & CF_SHUTW)))
+       if (((si->flags & (SI_FL_WANT_PUT|SI_FL_WAIT_ROOM)) == SI_FL_WANT_PUT) ||
+           ((si->flags & (SI_FL_WANT_GET|SI_FL_WAIT_DATA)) == SI_FL_WANT_GET))
                appctx_wakeup(si_appctx(si));
+       else
+               appctx_pause(si_appctx(si));
 }
 
 /*