]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[OPTIM] stats: check free space before trying to print
authorWilly Tarreau <w@1wt.eu>
Sun, 11 Oct 2009 21:35:10 +0000 (23:35 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 11 Oct 2009 21:35:10 +0000 (23:35 +0200)
This alone makes a typical HTML stats dump consume 10% CPU less,
because we avoid doing complex printf calls to drop them later.
Only a few common cases have been checked, those which are very
likely to run for nothing.

include/proto/buffers.h
src/dumpstats.c

index 801ea1a1d1f4b5b724e410a96c139db6394c07b5..6f10553b0e612447302274b88e285dc782466a7b 100644 (file)
@@ -288,6 +288,14 @@ static inline int buffer_contig_space(struct buffer *buf)
        return ret;
 }
 
+/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
+static inline int buffer_almost_full(struct buffer *buf)
+{
+       if (buffer_contig_space(buf) < buf->size / 4)
+               return 1;
+       return 0;
+}
+
 /*
  * Return the max amount of bytes that can be read from the buffer at once.
  * Note that this may be lower than the actual buffer length when the data
index 6d42b41279a4e0b6bccee37bb67026c4d883ac8f..5e7312f671867df76c899638109d6886cacc02c8 100644 (file)
@@ -540,6 +540,12 @@ void stats_io_handler(struct stream_interface *si)
                        break;
                }
                else if (si->st0 == STAT_CLI_GETREQ) {
+                       /* ensure we have some output room left in the event we
+                        * would want to return some info right after parsing.
+                        */
+                       if (buffer_almost_full(si->ib))
+                               break;
+
                        reql = buffer_si_peekline(si->ob, trash, sizeof(trash));
                        if (reql <= 0) { /* closed or EOL not found */
                                if (reql == 0)
@@ -1121,6 +1127,8 @@ int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri)
        case DATA_ST_LIST:
                /* dump proxies */
                while (s->data_ctx.stats.px) {
+                       if (buffer_almost_full(rep))
+                               return 0;
                        px = s->data_ctx.stats.px;
                        /* skip the disabled proxies and non-networked ones */
                        if (px->state != PR_STSTOPPED && (px->cap & (PR_CAP_FE | PR_CAP_BE)))
@@ -1329,6 +1337,9 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
        case DATA_ST_PX_LI:
                /* stats.l has been initialized above */
                for (; s->data_ctx.stats.l != NULL; s->data_ctx.stats.l = l->next) {
+                       if (buffer_almost_full(rep))
+                               return 0;
+
                        l = s->data_ctx.stats.l;
                        if (!l->counters)
                                continue;
@@ -1418,9 +1429,11 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
        case DATA_ST_PX_SV:
                /* stats.sv has been initialized above */
                for (; s->data_ctx.stats.sv != NULL; s->data_ctx.stats.sv = sv->next) {
-
                        int sv_state; /* 0=DOWN, 1=going up, 2=going down, 3=UP, 4,5=NOLB, 6=unchecked */
 
+                       if (buffer_almost_full(rep))
+                               return 0;
+
                        sv = s->data_ctx.stats.sv;
 
                        if (s->data_ctx.stats.flags & STAT_BOUND) {