From 0a90cab44adb08857ca04962072e773cfa73ad8b Mon Sep 17 00:00:00 2001
From: Deomid Ryabkov <rojer@cesanta.com>
Date: Wed, 21 Mar 2018 22:00:58 +0000
Subject: [PATCH] Improve mbuf allocation behavior

 * Limit total amount of headroom, in absolute terms (`MBUF_SIZE_MAX_HEADROOM`).
 * If unable to allocate with headroom, fall back to allocating the required minimum.
 * For mOS, set default `MBUF_SIZE_MULTIPLIER` to 2 to avoid floating point operations.
   Since max headroom size is now capped to 128 bytes, this will not result in much of a bloat.

PUBLISHED_FROM=11d4fc65a46a805bb7c8960f89a3d0b753c58bb8
---
 mongoose.c | 17 ++++++++++++++---
 mongoose.h |  8 ++++++++
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/mongoose.c b/mongoose.c
index 8e7bd8b28..5140a0acb 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -1470,10 +1470,21 @@ size_t mbuf_insert(struct mbuf *a, size_t off, const void *buf, size_t len) {
     }
     a->len += len;
   } else {
-    size_t new_size = (size_t)((a->len + len) * MBUF_SIZE_MULTIPLIER);
-    if ((p = (char *) MBUF_REALLOC(a->buf, new_size)) != NULL) {
+    size_t min_size = (a->len + len);
+    size_t new_size = (size_t)(min_size * MBUF_SIZE_MULTIPLIER);
+    if (new_size - min_size > MBUF_SIZE_MAX_HEADROOM) {
+      new_size = min_size + MBUF_SIZE_MAX_HEADROOM;
+    }
+    p = (char *) MBUF_REALLOC(a->buf, new_size);
+    if (p == NULL && new_size != min_size) {
+      new_size = min_size;
+      p = (char *) MBUF_REALLOC(a->buf, new_size);
+    }
+    if (p != NULL) {
       a->buf = p;
-      memmove(a->buf + off + len, a->buf + off, a->len - off);
+      if (off != a->len) {
+        memmove(a->buf + off + len, a->buf + off, a->len - off);
+      }
       if (buf != NULL) memcpy(a->buf + off, buf, len);
       a->len += len;
       a->size = new_size;
diff --git a/mongoose.h b/mongoose.h
index f8030d52a..c668594a5 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -1963,6 +1963,14 @@ extern "C" {
 #define MBUF_SIZE_MULTIPLIER 1.5
 #endif
 
+#ifndef MBUF_SIZE_MAX_HEADROOM
+#ifdef BUFSIZ
+#define MBUF_SIZE_MAX_HEADROOM BUFSIZ
+#else
+#define MBUF_SIZE_MAX_HEADROOM 1024
+#endif
+#endif
+
 /* Memory buffer descriptor */
 struct mbuf {
   char *buf;   /* Buffer pointer */
-- 
GitLab