]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add isc_buffer_setmctx() and isc_buffer_clearmctx() function
authorOndřej Surý <ondrej@isc.org>
Fri, 16 Dec 2022 10:43:20 +0000 (11:43 +0100)
committerOndřej Surý <ondrej@isc.org>
Tue, 20 Dec 2022 18:13:48 +0000 (19:13 +0100)
Add two extra functions needed by StreamDNS:

1. isc_buffer_setmctx() sets the buffer internal memory context, so we
   can use isc_buffer_reserve() on the buffer.  For this, we also need
   to track whether the .base was dynamically allocated or not.  This
   needs to be called after isc_buffer_init() and before first
   isc_buffer_reserve() call.

2. isc_buffer_clearmctx() clears the buffer internal memory context, and
   frees any dynamically allocated buffer.  This needs to be called
   after the last isc_buffer_reserve() call and before calling the
   isc_buffer_invalidate()

lib/isc/include/isc/buffer.h

index 081f26dcdf32fcf5425c9856e8d1424547b89497..2877d211791d76cad3530cc58cda925ed5300d02 100644 (file)
@@ -179,17 +179,16 @@ struct isc_buffer {
        unsigned int used;
        unsigned int current;
        unsigned int active;
-       /*! The extra bytes allocated for dynamic buffer */
-       unsigned int extra;
        /*@}*/
+       /*! The extra bytes allocated for static buffer */
+       unsigned int extra;
+       bool         dynamic;
        /*! linkable */
        ISC_LINK(isc_buffer_t) link;
        /*! private internal elements */
        isc_mem_t *mctx;
 };
 
-#define ISC_BUFFER_STATIC_SIZE 512
-
 /***
  *** Functions
  ***/
@@ -210,6 +209,15 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
  *\li  Changing the buffer's length field is not permitted.
  */
 
+static inline void
+isc_buffer_setmctx(isc_buffer_t *b, isc_mem_t *mctx);
+static inline void
+isc_buffer_clearmctx(isc_buffer_t *b);
+/*!<
+ * \brief Sets/Clears the internal memory context, so isc_buffer_reserve() can
+ * be used on previously 'static' buffer.
+ */
+
 static inline isc_result_t
 isc_buffer_reserve(isc_buffer_t *dynbuffer, unsigned int size);
 /*!<
@@ -1073,17 +1081,35 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dbufp,
 
        isc_buffer_init(dbuf, bdata, length);
        dbuf->extra = length;
-       dbuf->mctx = mctx;
+       isc_buffer_setmctx(dbuf, mctx);
 
        *dbufp = dbuf;
 }
 
+static inline void
+isc_buffer_setmctx(isc_buffer_t *b, isc_mem_t *mctx) {
+       REQUIRE(ISC_BUFFER_VALID(b));
+
+       b->mctx = mctx;
+}
+
+static inline void
+isc_buffer_clearmctx(isc_buffer_t *b) {
+       REQUIRE(ISC_BUFFER_VALID(b));
+
+       if (b->dynamic) {
+               isc_mem_put(b->mctx, b->base, b->length);
+               b->dynamic = false;
+       }
+
+       b->mctx = NULL;
+}
+
 static inline isc_result_t
 isc_buffer_reserve(isc_buffer_t *dbuf, unsigned int size) {
        REQUIRE(ISC_BUFFER_VALID(dbuf));
 
-       size_t   len;
-       uint8_t *bdata = (uint8_t *)dbuf + sizeof(*dbuf);
+       size_t len;
 
        len = dbuf->length;
        if ((len - dbuf->used) >= size) {
@@ -1107,9 +1133,11 @@ isc_buffer_reserve(isc_buffer_t *dbuf, unsigned int size) {
                return (ISC_R_NOMEMORY);
        }
 
-       if (dbuf->base == bdata) {
+       if (!dbuf->dynamic) {
+               void *old_base = dbuf->base;
                dbuf->base = isc_mem_get(dbuf->mctx, len);
-               memmove(dbuf->base, bdata, dbuf->used);
+               memmove(dbuf->base, old_base, dbuf->used);
+               dbuf->dynamic = true;
        } else {
                dbuf->base = isc_mem_reget(dbuf->mctx, dbuf->base, dbuf->length,
                                           len);
@@ -1126,15 +1154,11 @@ isc_buffer_free(isc_buffer_t **dbufp) {
 
        isc_buffer_t *dbuf = *dbufp;
        isc_mem_t    *mctx = dbuf->mctx;
-       uint8_t      *bdata = (uint8_t *)dbuf + sizeof(*dbuf);
        unsigned int  extra = dbuf->extra;
 
        *dbufp = NULL; /* destroy external reference */
-       dbuf->mctx = NULL;
 
-       if (dbuf->base != bdata) {
-               isc_mem_put(mctx, dbuf->base, dbuf->length);
-       }
+       isc_buffer_clearmctx(dbuf);
 
        isc_buffer_invalidate(dbuf);
        isc_mem_put(mctx, dbuf, sizeof(*dbuf) + extra);