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

Detailed Description

Outline

Purpose

Provide a thread-enabled adapter for the allocator protocol.

Classes

See also
bslma_allocator, bdlma_concurrentmultipool

Description

This component provides an adapter, bdlma::ConcurrentAllocatorAdapter, that implements the bslma::Allocator protocol and provides synchronization for operations on an allocator supplied at construction using a mutex also supplied at construction.

,-----------------------------------.
`-----------------------------------'
| ctor/dtor
V
,-----------------.
( bslma::Allocator )
`-----------------'
allocate
deallocate
Definition bdlma_concurrentallocatoradapter.h:288

Thread Safety

bdlma::ConcurrentAllocatorAdapter is thread-enabled, meaning any operation on the same instance can be safely invoked from any thread.

Usage

This section illustrates intended use of this component.

Example 1: Basic Usage

In the following usage example, we develop a simple AddressBook class containing two thread-enabled vectors of strings: one for names, the other for addresses. We use a bdlma::ConcurrentAllocatorAdapter to synchronize memory allocations across our two thread-enabled vectors. For the purpose of this discussion, we first define a simple thread-enabled vector:

template <class TYPE>
class ThreadEnabledVector {
// This class defines a trivial thread-enabled vector.
// DATA
mutable bslmt::Mutex d_mutex; // synchronize access
bsl::vector<TYPE> d_elements; // underlying list of strings
// NOT IMPLEMENTED
ThreadEnabledVector(const ThreadEnabledVector&);
ThreadEnabledVector& operator=(const ThreadEnabledVector&);
public:
// CREATORS
ThreadEnabledVector(bslma::Allocator *basicAllocator = 0)
// Create a thread-enabled vector. Optionally specify a
// 'basicAllocator' used to supply memory. If 'basicAllocator' is
// 0, the currently installed default allocator is used.
: d_elements(basicAllocator)
{
}
~ThreadEnabledVector() {}
// Destroy this thread-enabled vector object.
// MANIPULATORS
int pushBack(const TYPE& value)
// Append the specified 'value' to this thread-enabled vector and
// return the index of the new element.
{
d_elements.push_back(value);
return static_cast<int>(d_elements.size()) - 1;
}
void set(int index, const TYPE& value)
// Set the element at the specified 'index' in this thread-enabled
// vector to the specified 'value'. The behavior is undefined
// unless '0 <= index < length()'.
{
d_elements[index] = value;
}
// ACCESSORS
TYPE element(int index) const
// Return the value of the element at the specified 'index' in this
// thread-enabled vector. Note that elements are returned *by*
// *value* because references to elements managed by this container
// may be invalidated by another thread.
{
return d_elements[index];
}
int length() const
// Return the number of elements in this thread-enabled vector.
{
return static_cast<int>(d_elements.size());
}
};
size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the number of elements in this vector.
Definition bslstl_vector.h:2664
Definition bslstl_vector.h:1025
void push_back(const VALUE_TYPE &value)
Definition bslstl_vector.h:3760
Definition bslma_allocator.h:457
Definition bslmt_lockguard.h:234
Definition bslmt_mutex.h:315

We use this thread-enabled vector to create a AddressBook class. However, we use the bdlma::ConcurrentAllocatorAdapter to prevent our two (thread-enabled) vectors from attempting synchronous memory allocations from our (potentially) non-thread safe bslma::Allocator. Note that we define a local class, AddressBook_PrivateData, in order to guarantee that d_allocatorAdapter and d_mutex are initialized before the thread-enabled vectors that depend on them:

struct AddressBook_PrivateData {
// This 'struct' contains a mutex and an allocator adapter. The
// 'AddressBook' class will inherit from this structure, ensuring that
// the mutex and adapter are initialized before other member variables
// that depend on them.
private:
// Not implemented:
AddressBook_PrivateData(const AddressBook_PrivateData&);
public:
bslmt::Mutex d_mutex; // synchronize allocator
d_allocatorAdapter; // adapter for allocator
AddressBook_PrivateData(bslma::Allocator *basicAllocator = 0)
// Create a empty AddressBook private data object. Optionally
// specify a 'basicAllocator' used to supply memory. If
// 'basicAllocator' is 0, the currently installed default allocator
// is used.
: d_allocatorAdapter(&d_mutex, basicAllocator)
{
}
};
class AddressBook : private AddressBook_PrivateData {
// This 'class' defines a thread-enabled AddressBook containing vectors
// of names and addresses. Note that this class uses private
// inheritance to ensure that the allocator adapter and mutex are
// initialized before the vectors of names and addresses.
// DATA
ThreadEnabledVector<bsl::string> d_names; // list of names
ThreadEnabledVector<bsl::string> d_addresses; // list of addresses
private:
// Not implemented:
AddressBook(const AddressBook&);
public:
// CREATORS
AddressBook(bslma::Allocator *basicAllocator = 0)
// Create an empty AddressBook for storing names and addresses.
// Optionally specify a 'basicAllocator' used to supply memory. If
// 'basicAllocator' is 0, the currently installed default allocator
// is used.
: AddressBook_PrivateData(basicAllocator)
, d_names(&d_allocatorAdapter)
, d_addresses(&d_allocatorAdapter)
{
}
~AddressBook()
// Destroy this AddressBook.
{
}
// MANIPULATORS
int addName(const bsl::string& name)
// Add the specified 'name' to this AddressBook and return the
// index of the newly-added name.
{
return d_names.pushBack(name);
}
int addAddress(const bsl::string& address)
// Add the specified 'address' to this AddressBook and return the
// index of the newly-added address.
{
return d_addresses.pushBack(address);
}
// ACCESSORS
bsl::string name(int index) const
// Return the value of the name at the specified 'index' in this
// AddressBook.
{
return d_names.element(index);
}
bsl::string address(int index) const
// Return the value of the address at the specified 'index' in this
// AddressBook.
{
return d_addresses.element(index);
}
int numNames() const
// Return the number of names in this AddressBook.
{
return d_names.length();
}
int numAddresses() const
// Return the number of addresses in this AddressBook.
{
return d_addresses.length();
}
};
Definition bslstl_string.h:1281