From: Arran Cudbard-Bell Date: Thu, 21 Apr 2022 16:48:10 +0000 (-0500) Subject: Add temporary thread local dbuff buffers too X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e7e7461dc5536ebfdcc70f733b2c777810f1577;p=thirdparty%2Ffreeradius-server.git Add temporary thread local dbuff buffers too --- diff --git a/src/lib/util/dbuff.c b/src/lib/util/dbuff.c index d4c43b78f1c..7eca599368e 100644 --- a/src/lib/util/dbuff.c +++ b/src/lib/util/dbuff.c @@ -321,3 +321,34 @@ int fr_dbuff_trim_talloc(fr_dbuff_t *dbuff, size_t len) return 0; } + +/** Reset a talloced buffer to its initial length, clearing any data stored + * + * @param[in] dbuff to reset. + * @return + * - 0 on success. + * - -1 on failure - markers present pointing past the end of string data. + */ +int fr_dbuff_reset_talloc(fr_dbuff_t *dbuff) +{ + fr_dbuff_uctx_talloc_t *tctx = dbuff->uctx; + + CHECK_DBUFF_INIT(dbuff); + + fr_dbuff_set_to_start(dbuff); /* Clear data */ + + if (fr_dbuff_used(dbuff) != tctx->init) { + uint8_t *new_buff; + + new_buff = talloc_realloc(tctx->ctx, dbuff->buff, uint8_t, tctx->init); + if (!new_buff) { + fr_strerror_printf("Failed reallocing from %zu to %zu", + talloc_array_length(dbuff->buff), tctx->init); + return -1; + } + dbuff->buff = new_buff; + fr_dbuff_update(dbuff, new_buff, tctx->init); + } + + return 0; +} diff --git a/src/lib/util/dbuff.h b/src/lib/util/dbuff.h index d64366346a2..bae50093e63 100644 --- a/src/lib/util/dbuff.h +++ b/src/lib/util/dbuff.h @@ -374,6 +374,8 @@ size_t _fr_dbuff_extend_talloc(fr_dbuff_t *dbuff, size_t extension); int fr_dbuff_trim_talloc(fr_dbuff_t *dbuff, size_t len); +int fr_dbuff_reset_talloc(fr_dbuff_t *dbuff); + /** Talloc extension structure use by #fr_dbuff_init_talloc * @private * @@ -522,6 +524,39 @@ static inline fr_dbuff_t *fr_dbuff_init_fd(fr_dbuff_t *dbuff, fr_dbuff_uctx_fd_t char const * : true \ ) \ } + +/** Structure to encapsulate a thread local dbuff information + * + */ +typedef struct { + fr_dbuff_t dbuff; //!< Thread local dbuff. + fr_dbuff_uctx_talloc_t tctx; //!< Thread local tctx. +} fr_dbuff_thread_local_t; + +static inline int _dbuff_thread_local_free(void *dbtl) +{ + return talloc_free(dbtl); +} + +/** Create a function local and thread local extensible dbuff + * + * @param[out] _dbuff_out Where to write a pointer to the thread local dbuff + * @param[in] _init Initial size for the dbuff buffer. + * @param[in] _max Maximum size of the dbuff buffer. + */ +#define FR_DBUFF_TALLOC_THREAD_LOCAL(_out, _init, _max) \ +{ \ + static _Thread_local fr_dbuff_thread_local_t *_dbuff_t_local; \ + if (!_dbuff_t_local) { \ + fr_dbuff_thread_local_t *dbtl = talloc_zero(NULL, fr_dbuff_thread_local_t); \ + fr_dbuff_init_talloc(dbtl, &dbtl->dbuff, &dbtl->tctx, _init, _max); \ + fr_atexit_thread_local(_dbuff_t_local, _dbuff_thread_local_free, dbtl); \ + *(_out) = &_dbuff_t_local->dbuff; \ + } else { \ + fr_dbuff_reset_talloc(&_dbuff_t_local->dbuff); \ + *(_out) = &_dbuff_t_local->dbuff; \ + } \ +} /** @} */ /** @name Extension requests