mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-04 00:25:29 +00:00
Add isc_buffer_setmctx() and isc_buffer_clearmctx() function
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()
This commit is contained in:
@@ -179,17 +179,16 @@ struct isc_buffer {
|
|||||||
unsigned int used;
|
unsigned int used;
|
||||||
unsigned int current;
|
unsigned int current;
|
||||||
unsigned int active;
|
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 */
|
/*! linkable */
|
||||||
ISC_LINK(isc_buffer_t) link;
|
ISC_LINK(isc_buffer_t) link;
|
||||||
/*! private internal elements */
|
/*! private internal elements */
|
||||||
isc_mem_t *mctx;
|
isc_mem_t *mctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ISC_BUFFER_STATIC_SIZE 512
|
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*** Functions
|
*** 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.
|
*\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
|
static inline isc_result_t
|
||||||
isc_buffer_reserve(isc_buffer_t *dynbuffer, unsigned int size);
|
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);
|
isc_buffer_init(dbuf, bdata, length);
|
||||||
dbuf->extra = length;
|
dbuf->extra = length;
|
||||||
dbuf->mctx = mctx;
|
isc_buffer_setmctx(dbuf, mctx);
|
||||||
|
|
||||||
*dbufp = dbuf;
|
*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
|
static inline isc_result_t
|
||||||
isc_buffer_reserve(isc_buffer_t *dbuf, unsigned int size) {
|
isc_buffer_reserve(isc_buffer_t *dbuf, unsigned int size) {
|
||||||
REQUIRE(ISC_BUFFER_VALID(dbuf));
|
REQUIRE(ISC_BUFFER_VALID(dbuf));
|
||||||
|
|
||||||
size_t len;
|
size_t len;
|
||||||
uint8_t *bdata = (uint8_t *)dbuf + sizeof(*dbuf);
|
|
||||||
|
|
||||||
len = dbuf->length;
|
len = dbuf->length;
|
||||||
if ((len - dbuf->used) >= size) {
|
if ((len - dbuf->used) >= size) {
|
||||||
@@ -1107,9 +1133,11 @@ isc_buffer_reserve(isc_buffer_t *dbuf, unsigned int size) {
|
|||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbuf->base == bdata) {
|
if (!dbuf->dynamic) {
|
||||||
|
void *old_base = dbuf->base;
|
||||||
dbuf->base = isc_mem_get(dbuf->mctx, len);
|
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 {
|
} else {
|
||||||
dbuf->base = isc_mem_reget(dbuf->mctx, dbuf->base, dbuf->length,
|
dbuf->base = isc_mem_reget(dbuf->mctx, dbuf->base, dbuf->length,
|
||||||
len);
|
len);
|
||||||
@@ -1126,15 +1154,11 @@ isc_buffer_free(isc_buffer_t **dbufp) {
|
|||||||
|
|
||||||
isc_buffer_t *dbuf = *dbufp;
|
isc_buffer_t *dbuf = *dbufp;
|
||||||
isc_mem_t *mctx = dbuf->mctx;
|
isc_mem_t *mctx = dbuf->mctx;
|
||||||
uint8_t *bdata = (uint8_t *)dbuf + sizeof(*dbuf);
|
|
||||||
unsigned int extra = dbuf->extra;
|
unsigned int extra = dbuf->extra;
|
||||||
|
|
||||||
*dbufp = NULL; /* destroy external reference */
|
*dbufp = NULL; /* destroy external reference */
|
||||||
dbuf->mctx = NULL;
|
|
||||||
|
|
||||||
if (dbuf->base != bdata) {
|
isc_buffer_clearmctx(dbuf);
|
||||||
isc_mem_put(mctx, dbuf->base, dbuf->length);
|
|
||||||
}
|
|
||||||
|
|
||||||
isc_buffer_invalidate(dbuf);
|
isc_buffer_invalidate(dbuf);
|
||||||
isc_mem_put(mctx, dbuf, sizeof(*dbuf) + extra);
|
isc_mem_put(mctx, dbuf, sizeof(*dbuf) + extra);
|
||||||
|
Reference in New Issue
Block a user