BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlcc_sharedobjectpool

Detailed Description

Outline

Purpose

Provide a thread-safe pool of shared objects.

Classes

See also
bslstl_sharedptr

Description

This component provides a generic thread-safe pool of shared objects, bdlcc::SharedObjectPool, using the acquire-release idiom. The functionality provided is identical to bdlcc::ObjectPool, except that getObject returns efficiently-constructed bsl::shared_ptr objects instead of raw pointers. For client code that needs to provide shared access to objects in the pool, this functionality saves an additional allocation for the shared pointer itself. Since the shared pointer and the object are contiguous in memory, this component also tends to improve performance by reducing "cache misses."

Object Construction and Destruction

The object pool owns the memory required to store the pooled objects and the shared-pointer representations, and manages the construction, resetting, and destruction of objects. The user may supply functors to create objects and to reset them to a valid state for their return to the pool; alternatively, this component supplies reasonable defaults. Upon destruction the object pool deallocates all memory associated with the objects in the pool. The behavior is undefined if there are any outstanding shared pointer references to the objects in the pool when it is destroyed.

Creator and Resetter Template Contract

bdlcc::SharedObjectPool is templated on two types CREATOR and RESETTER in addition to the underlying object TYPE. Objects of these types may be provided at construction (or defaults may be used). The creator will be invoked as: void(*)(void*, bslma::Allocator*). The resetter will be invoked as: void(*)(TYPE*). The creator functor will be called to construct a new object of the parameterized TYPE when the pool must be expanded (and thus it will typically invoke placement new and pass its allocator argument to the constructor of TYPE). The resetter functor will be called before each object is returned to the pool, and is required to put the object into a state such that it is ready to be reused. The defaults for these types are as follows:

Definition bdlcc_objectpool.h:428
Forward declaration.
Definition bslstl_function.h:934

bdlcc::ObjectPoolFunctors::Nil is a no-op; it is only suitable if the objects stored in the pool are always in a valid state to be reused. Otherwise - that is, if anything must be done to render the objects ready for reuse - another kind of RESETTER should be provided (so long as that type supplies void(*)(TYPE*)). In bdlcc::ObjectPoolFunctors, the classes Clear, RemoveAll, and Reset are all acceptable types for RESETTER. Since these "functor" types are fully inline, it is generally most efficient to define reset() (or clear() or removeAll()) in the underlying TYPE and allow the functor to call that method. The CREATOR functor defaults to an object that invokes the default constructor with placement new, passing the allocator argument if the type traits of the object indicate it uses an allocator (see bslma_usesbslmaallocator ). If a custom creator functor or a custom CREATOR type is specified, it is the user's responsibility to ensure that it correctly passes its allocator argument through to the constructor of TYPE if TYPE uses allocator.

Exception Safety

There are two potential sources of exceptions in this component: memory allocation and object construction. The object pool is exception-neutral with full guarantee of rollback for the following methods: if an exception is thrown in getObject, reserveCapacity, or increaseCapacity, then the pool is in a valid unmodified state (i.e., identical to prior the call to getObject). No other method of bdlcc::SharedObjectPool can throw.

Pool Replenishment Policy

The growBy parameter can be specified in the pool's constructor to instruct the pool how it is to increase its capacity each time the pool is depleted. If growBy is positive, the pool always replenishes itself with enough objects so that it can satisfy at least growBy object requests before the next replenishment. If growBy is negative, the pool will increase its capacity geometrically until it exceeds the internal maximum (which itself is implementation-defined), and after that it will be replenished with constant number of objects. If growBy is not specified, an implementation-defined default will be chosen. The behavior is undefined if growBy is 0.

Usage

This component is intended to improve the efficiency of code which provides shared pointers to pooled objects. As an example, consider a class which maintains a pool of vector<char> objects and provides shared pointers to them. Using bdlcc::ObjectPool, the class might be implemented like this:

typedef vector<char> CharArray;
class SlowCharArrayPool {
bdlma::ConcurrentPoolAllocator d_spAllocator; // alloc. shared pointer
bdlcc::ObjectPool<CharArray> d_charArrayPool; // supply charArrays
static void createCharArray(void *address, bslma::Allocator *allocator)
{
new (address) CharArray(allocator);
}
static void resetAndReturnCharArray(
CharArray *charArray,
{
charArray->clear();
pool->releaseObject(charArray);
}
private:
// Not implemented:
SlowCharArrayPool(const SlowCharArrayPool&);
public:
SlowCharArrayPool(bslma::Allocator *basicAllocator = 0)
: d_spAllocator(basicAllocator)
, d_charArrayPool(bdlf::BindUtil::bind(
&SlowCharArrayPool::createCharArray,
bdlf::PlaceHolders::_1,
basicAllocator),
-1,
basicAllocator)
{
}
void getCharArray(bsl::shared_ptr<CharArray> *charArray_sp)
{
charArray_sp->reset(d_charArrayPool.getObject(),
&SlowCharArrayPool::resetAndReturnCharArray,
&d_charArrayPool),
&d_spAllocator);
}
};
Definition bdlcc_objectpool.h:686
void releaseObject(TYPE *object)
Definition bdlcc_objectpool.h:1313
TYPE * getObject()
Definition bdlcc_objectpool.h:1214
static Bind< bslmf::Nil, t_FUNC, Bind_BoundTuple0 > bind(t_FUNC func)
Definition bdlf_bind.h:1830
Definition bdlma_concurrentpoolallocator.h:635
Definition bslstl_sharedptr.h:1830
void reset() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_sharedptr.h:5358
Definition bslma_allocator.h:457
const PlaceHolder< 1 > _1
Definition bdlf_bind.h:976

Note that SlowCharArrayPool must allocate the shared pointer itself from its d_spAllocator in addition to allocating the charArray from its pool. Moreover, note that since the same function will handle resetting the object and returning it to the pool, we must define a special function for that purpose and bind its arguments.

We can solve both of these issues by using bdlcc::SharedObjectPool instead:

class FastCharArrayPool {
CharArray,
CharArrayPool d_charArrayPool; // supply charArrays
static void createCharArray(void *address, bslma::Allocator *allocator)
{
new (address) CharArray(allocator);
}
private:
// Not implemented:
FastCharArrayPool(const FastCharArrayPool&);
public:
FastCharArrayPool(bslma::Allocator *basicAllocator = 0)
: d_charArrayPool(bdlf::BindUtil::bind(
&FastCharArrayPool::createCharArray,
bdlf::PlaceHolders::_1,
bdlf::PlaceHolders::_2),
-1,
basicAllocator)
{
}
void getCharArray(bsl::shared_ptr<CharArray> *charArray_sp)
{
*charArray_sp = d_charArrayPool.getObject();
}
};
Definition bdlcc_objectpool.h:460
Definition bdlcc_sharedobjectpool.h:366
bsl::function< void(void *, bslma::Allocator *)> DefaultCreator
Definition bdlcc_objectpool.h:419

Now the shared pointer and the object are allocated as one unit from the same allocator. In addition, the resetter method is a fully-inlined class that is only responsible for resetting the object, improving efficiency and simplifying the design. We can verify that use of bdlcc::SharedObjectPool reduces the number of allocation requests:

bslma::TestAllocator slowAllocator, fastAllocator;
{
SlowCharArrayPool slowPool(&slowAllocator);
FastCharArrayPool fastPool(&fastAllocator);
fastPool.getCharArray(&charArray_sp);
slowPool.getCharArray(&charArray_sp); // throw away the first array
}
assert(2 == slowAllocator.numAllocations());
assert(1 == fastAllocator.numAllocations());
assert(0 == slowAllocator.numBytesInUse());
assert(0 == fastAllocator.numBytesInUse());
Definition bslma_testallocator.h:384
bsls::Types::Int64 numBytesInUse() const
Definition bslma_testallocator.h:1111
bsls::Types::Int64 numAllocations() const
Definition bslma_testallocator.h:1081