aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libmdsclient/inbound.c18
-rw-r--r--src/libmdsclient/inbound.h5
2 files changed, 17 insertions, 6 deletions
diff --git a/src/libmdsclient/inbound.c b/src/libmdsclient/inbound.c
index cb151a6..58251fd 100644
--- a/src/libmdsclient/inbound.c
+++ b/src/libmdsclient/inbound.c
@@ -80,22 +80,32 @@ void libmds_message_destroy(libmds_message_t* restrict this)
* be done even if initialisation fails
*
* @param this The message
+ * @param pool Message allocation pool, may be `NULL`
* @return The duplicate, you do not need to call `libmds_message_destroy`
* on it before you call `free` on it. However, you cannot use
* this is an `libmds_message_t` array (libmds_message_t*), only
* in an `libmds_message_t*` array (libmds_message_t**).
*/
-libmds_message_t* libmds_message_duplicate(libmds_message_t* restrict this)
+libmds_message_t* libmds_message_duplicate(libmds_message_t* restrict this, libmds_mpool_t* restrict pool)
{
- size_t flattened_size, i, n = this->header_count;
+ size_t flattened_size, reused, i, n = this->header_count;
libmds_message_t* rc;
flattened_size = sizeof(libmds_message_t) + this->buffer_off * sizeof(char) + n * sizeof(void*);
- if (rc = malloc(flattened_size), rc == NULL)
+ repoll:
+ reused = 0;
+ rc = pool == NULL ? NULL : libmds_mpool_poll(pool);
+ if (rc != NULL)
+ if ((reused = rc->flattened) < flattened_size)
+ {
+ free(rc);
+ goto repoll;
+ }
+ if ((rc == NULL) && (rc = malloc(flattened_size), rc == NULL))
return NULL;
*rc = *this;
- rc->flattened = flattened_size;
+ rc->flattened = reused ? reused : flattened_size;
rc->buffer_size = this->buffer_off;
rc->buffer = ((char*)rc) + sizeof(libmds_message_t) / sizeof(char);
diff --git a/src/libmdsclient/inbound.h b/src/libmdsclient/inbound.h
index 05fcc74..85d2fcc 100644
--- a/src/libmdsclient/inbound.h
+++ b/src/libmdsclient/inbound.h
@@ -232,13 +232,14 @@ void libmds_message_destroy(libmds_message_t* restrict this);
* be done even if initialisation fails
*
* @param this The message
+ * @param pool Message allocation pool, may be `NULL`
* @return The duplicate, you do not need to call `libmds_message_destroy`
* on it before you call `free` on it. However, you cannot use
* this is an `libmds_message_t` array (libmds_message_t*), only
* in an `libmds_message_t*` array (libmds_message_t**).
*/
-__attribute__((nonnull, malloc, warn_unused_result))
-libmds_message_t* libmds_message_duplicate(libmds_message_t* restrict this);
+__attribute__((nonnull(1), malloc, warn_unused_result))
+libmds_message_t* libmds_message_duplicate(libmds_message_t* restrict this, libmds_mpool_t* restrict pool);
/**
* Read the next message from a file descriptor