]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add temporary thread local dbuff buffers too
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 21 Apr 2022 16:48:10 +0000 (11:48 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 21 Apr 2022 16:48:23 +0000 (11:48 -0500)
src/lib/util/dbuff.c
src/lib/util/dbuff.h

index d4c43b78f1c3dc914f4c49644f800c6c8cbb9df1..7eca599368ee7c0fd9a4b6c2671f94ddef441008 100644 (file)
@@ -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;
+}
index d64366346a2dd9fbc19ce21dcdc7b17442307b37..bae50093e63a2c0edbd54392097971e3139c771f 100644 (file)
@@ -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