return m;
}
-
-/** Reserve a message
- *
- * A later call to fr_message_alloc() will allocate the correct
- * packet ring buffer size. This call just allocates a message
- * header, and reserves space for the packet.
- *
- * If the caller later decides that the message is not needed, he
- * should call fr_message_free() to free the message.
- *
- * We assume that the caller will call fr_message_reserve(), and then
- * almost immediately fr_message_alloc(). Multiple calls in series
- * to fr_message_reserve() MUST NOT be done. The caller could also
- * just call fr_ring_buffer_alloc(m->rb, size) if they wanted, and
- * then udpate m->data_size by hand...
- *
- * The message is returned
+/** Allocate a fr_message_t, WITHOUT a ring buffer.
*
* @param[in] ms the message set
- * @param[in] reserve_size to reserve
+ * @param[out] p_mr the message ring we allocated the message from
+ * @param[out] p_cleaned a flag to indicate if we cleaned the message array
* @return
* - NULL on error
* - fr_message_t* on success
*/
-fr_message_t *fr_message_reserve(fr_message_set_t *ms, size_t reserve_size)
+static fr_message_t *fr_message_alloc_internal(fr_message_set_t *ms, fr_message_ring_t **p_mr, bool *p_cleaned)
{
int i;
- bool cleaned_up = false;
fr_message_t *m;
fr_message_ring_t *mr;
- fr_ring_buffer_t *rb;
-
-#ifndef NDEBUG
- (void) talloc_get_type_abort(ms, fr_message_set_t);
-#endif
-
- if (reserve_size > ms->max_allocation) return NULL;
ms->allocated++;
+ *p_cleaned = false;
+ *p_mr = NULL;
/*
* Grab the current message array. In the general case,
m = fr_message_ring_alloc(ms, mr, true);
if (m) {
MPRINT("ALLOC normal\n");
- goto get_rb;
+ *p_mr = mr;
+ return m;
}
MPRINT("CLEANING UP (%zd - %zd = %zd)\n", ms->allocated, ms->freed,
* Else the buffer is full. Do a global cleanup.
*/
fr_message_cleanup(ms, 128);
- cleaned_up = true;
+ *p_cleaned = true;
/*
* If we're lucky, the cleanup has given us a new
m = fr_message_ring_alloc(ms, mr, true);
if (m) {
MPRINT("ALLOC after cleanup\n");
- goto get_rb;
+ *p_mr = mr;
+ return m;
}
/*
ms->m_current = i;
MPRINT("ALLOC from changed ring buffer\n");
MPRINT("SET MR to changed %d\n", ms->m_current);
- goto get_rb;
+ *p_mr = mr;
+ return m;
}
}
m = fr_message_ring_alloc(ms, mr, false);
if (!m) return NULL;
MPRINT("ALLOC after doubled message ring\n");
-
-get_rb:
+
+ *p_mr = mr;
+ return m;
+}
+
+
+/** Reserve a message
+ *
+ * A later call to fr_message_alloc() will allocate the correct
+ * packet ring buffer size. This call just allocates a message
+ * header, and reserves space for the packet.
+ *
+ * If the caller later decides that the message is not needed, he
+ * should call fr_message_free() to free the message.
+ *
+ * We assume that the caller will call fr_message_reserve(), and then
+ * almost immediately fr_message_alloc(). Multiple calls in series
+ * to fr_message_reserve() MUST NOT be done. The caller could also
+ * just call fr_ring_buffer_alloc(m->rb, size) if they wanted, and
+ * then udpate m->data_size by hand...
+ *
+ * The message is returned
+ *
+ * @param[in] ms the message set
+ * @param[in] reserve_size to reserve
+ * @return
+ * - NULL on error
+ * - fr_message_t* on success
+ */
+fr_message_t *fr_message_reserve(fr_message_set_t *ms, size_t reserve_size)
+{
+ int i;
+ bool cleaned_up = false;
+ fr_message_t *m;
+ fr_message_ring_t *mr;
+ fr_ring_buffer_t *rb;
+
+#ifndef NDEBUG
+ (void) talloc_get_type_abort(ms, fr_message_set_t);
+#endif
+
+ if (reserve_size > ms->max_allocation) return NULL;
+
+ /*
+ * Get a bare message.
+ */
+ m = fr_message_alloc_internal(ms, &mr, &cleaned_up);
+ if (!m) return NULL;
+
/*
* If the caller is not allocating any packet data, just
* return the empty message.