changeset 631:d5221299656a

Add new function th_ringbuf_init() and add "allocated" field to th_ringbuf_t to flag if the structure itself has been allocated by th_ringbuf_new() or not. Free structure in th_ringbuf_free() only if allocated flag is set.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 17 Jan 2020 20:07:25 +0200
parents d3aace9903fa
children 553db886533e
files th_datastruct.c th_datastruct.h
diffstat 2 files changed, 31 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/th_datastruct.c	Fri Jan 17 19:32:28 2020 +0200
+++ b/th_datastruct.c	Fri Jan 17 20:07:25 2020 +0200
@@ -322,28 +322,41 @@
 /*
  * Ringbuffers
  */
+int th_ringbuf_init(th_ringbuf_t *buf, const size_t size, void (*mdeallocator)(void *data))
+{
+    // Must have at least 2 elements
+    memset(buf, 0, sizeof(th_ringbuf_t));
+
+    if (size < 2)
+        return THERR_BOUNDS;
+
+    if ((buf->data = th_calloc(size, sizeof(void *))) == NULL)
+        return THERR_MALLOC;
+
+    buf->size = size;
+    buf->n = 0;
+    buf->deallocator = mdeallocator;
+
+    return THERR_OK;
+}
+
+
 th_ringbuf_t * th_ringbuf_new(const size_t size, void (*mdeallocator)(void *data))
 {
-    th_ringbuf_t *res;
+    th_ringbuf_t *buf;
+    int res;
 
-    // Must have at least 2 elements
-    if (size < 2)
+    if ((buf = th_malloc0(sizeof(th_ringbuf_t))) == NULL)
         return NULL;
 
-    if ((res = th_malloc0(sizeof(th_ringbuf_t))) == NULL)
-        return NULL;
-
-    if ((res->data = th_calloc(size, sizeof(void *))) == NULL)
+    if ((res = th_ringbuf_init(buf, size, mdeallocator)) != THERR_OK)
     {
-        th_free(res);
+        th_free(buf);
         return NULL;
     }
 
-    res->size = size;
-    res->n = 0;
-    res->deallocator = mdeallocator;
-
-    return res;
+    buf->allocated = TRUE;
+    return buf;
 }
 
 
@@ -370,7 +383,9 @@
     }
 
     th_free(buf->data);
-    th_free(buf);
+
+    if (buf->allocated)
+        th_free(buf);
 }
 
 
--- a/th_datastruct.h	Fri Jan 17 19:32:28 2020 +0200
+++ b/th_datastruct.h	Fri Jan 17 20:07:25 2020 +0200
@@ -61,9 +61,11 @@
     size_t size;    ///< Size of this ringbuffer in elements (aka pointers to data)
     size_t n;       ///< Number of elements currently in the ringbuffer (@p n <= @p size)
     void (*deallocator)(void *data); ///< De-allocator function that frees one element.
+    BOOL allocated;
 } th_ringbuf_t;
 
 
+int            th_ringbuf_init(th_ringbuf_t *buf, const size_t size, void (*mdeallocator)(void *data));
 th_ringbuf_t * th_ringbuf_new(const size_t size, void (*mdeallocator)(void *data));
 BOOL           th_ringbuf_grow(th_ringbuf_t *buf, const size_t n);
 void           th_ringbuf_free(th_ringbuf_t *buf);