Should the template function versions ensure is_trivially_destructible<T>? This should reject non POD allocations.
Sent with Proton Mail secure email. On Wednesday, December 6th, 2023 at 7:00 PM, Alan Carroll <a...@network-geographics.com> wrote: > Proposed Transaction based memory allocation API > > TSTxnAlloc > ********** > > Traffic Server Transaction based memory allocation. > > Synopsis > ======== > > .. code-block:: cpp > > #include <ts/ts.h> > > > .. function:: swoc::MemSpan<void> TSTxnAlloc(TSHttpTxn txn, size_t bytes) > > .. function:: swoc::MemSpan<void> TSTxnAllocAligned(TSHttpTxn txn, size_t > bytes, size_t align) > > .. function:: template < typename T > T * TSTxnAllocInstance(); > > .. function:: template < typename T > swoc::MemSpan<T> TSTxnAllocArray(size_t > count); > > .. function:: swoc::TextView TSTxnLocalizeString(TSHttpTxn txn, > swoc::TextView s) > .. function:: swoc::TextView TSTxnLocalizeCString(TSHttpTxn txn, char const * > s) > .. function:: template < typename F > void TSTxnFinalize(TSHttpTxn txn, F && > f) > > > Description > =========== > > These functions are used to allocate memory that has the same lifetime as a > transaction. This has two differences from > normal allocation which are frequently advantageous for plugins. > > * Allocation is much faster than :code:`malloc` or equivalent. > * The memory is released at the end of the transaction automatically. > > The only function in this group that does not allocate is > :func:`TSTxnFinalize`. Instead this provides a functor > which is invoked just before the transaction local memory is released. > > :func:`TSTxnAlloc` allocates a block of memory of size :arg:`bytes`. > > :func:`TSTxnAllocAligned` allocates a block of memory of size :arg:`bytes` > that is aligned at a multiple of :arg:`align`, > which must be a power of 2. > > :func:`TSTxnAllocInstance` allocates an instance of a type :code:`T` with the > required alignment for :arg:`T`, > calls the default constructor for :code:`T`, and the returns the pointer. > > :func:`TSTxnAllocArray` allocates a block of memory of size and alignment to > hold :arg:`count` instances of :code:`T`. These > are not initialized / constructed. > > :func:`TSTxnLocalizeString` copies the string :arg:`s` to transaction local > memory and returns a view of the copied string. > > :func:`TSTxnLocalizeCString` copies a C string (nul character terminated) > :arg:`s` to transaction local memory and returns a view of the copied string. > > :func:`TSTxnFinalize` creates a finalizer for the transaction which are > described in :ref:`finalizers`. > > Notes > ===== > > In general this memory should avoid referencing memory outside of transaction > local memory. Strings are the archetype > as a string is complete in itself and requires no cleanup beyond > deallocation. For variable sized structures it is > possible to use :code:`swoc::IntrusiveDList` to create lists which reside > entirely in transaction local memory and > therefore require no addtional cleanup. > > .. _finalizers:: > > Finalizers > ---------- > > If cleanup is unavoidable then a :em:`finalizer` can be used. This is a > functor that is invoked just before cleaning > up transaction local memory which is intended to perform addtional cleanup. > This imposes several restrictions > > * The finalizer itself must not require any cleanup beyond deallocation. One > aspect is the functor instance must > not contain any non-transaction local allocated memory. > * The finalizer must only do allocation related cleanup. It must not call any > TS plugion API calls. The transaction > object is likely to be in an unusable state when the finalizer is invoked. > > For an example finalizer, suppose the allocation is used to hold a > :code:`std::vector<size_t>`. Simply releasing the > > memory will leak the vector elements, so the vector must be destructed. This > can be handled by a finalizer that looks > like > > .. code-block:: cpp > > auto * vecp = TSTxnAllocInstance<std::vector<size_t>>(txn); > > TSTxnFinalizer(txn, = -> void { delete vecp; }); > > > The pointer to the allocated vector is captured by the lambda and when the > transaction local memory is released the > vector contents are also released. Be very very careful or (better) avoid > entirely capture by reference, as the target of the > reference is likely to be long out of scope when the finalizer is invoked. > > See also > ======== > > :manpage:`TSAPI(3ts)` > +