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)`
> +

Reply via email to