From: Alan T. DeKok Date: Sat, 19 Nov 2016 02:08:30 +0000 (-0500) Subject: split out allocate message from allocate ring buffer X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aa2e5b9fbab6b33d7a193ba57d67d5d9d89d408e;p=thirdparty%2Ffreeradius-server.git split out allocate message from allocate ring buffer --- diff --git a/src/util/message.c b/src/util/message.c index 03eb799ed6d..b9d3d8e09c0 100644 --- a/src/util/message.c +++ b/src/util/message.c @@ -785,45 +785,24 @@ static fr_message_t *fr_message_ring_alloc(fr_message_set_t *ms, fr_message_ring 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, @@ -834,7 +813,8 @@ fr_message_t *fr_message_reserve(fr_message_set_t *ms, size_t reserve_size) 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, @@ -844,7 +824,7 @@ fr_message_t *fr_message_reserve(fr_message_set_t *ms, size_t reserve_size) * 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 @@ -854,7 +834,8 @@ fr_message_t *fr_message_reserve(fr_message_set_t *ms, size_t reserve_size) m = fr_message_ring_alloc(ms, mr, true); if (m) { MPRINT("ALLOC after cleanup\n"); - goto get_rb; + *p_mr = mr; + return m; } /* @@ -878,7 +859,8 @@ fr_message_t *fr_message_reserve(fr_message_set_t *ms, size_t reserve_size) 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; } } @@ -914,8 +896,55 @@ fr_message_t *fr_message_reserve(fr_message_set_t *ms, size_t reserve_size) 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.