BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlma_concurrentallocatoradapter.h
Go to the documentation of this file.
1/// @file bdlma_concurrentallocatoradapter.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlma_concurrentallocatoradapter.h -*-C++-*-
8#ifndef INCLUDED_BDLMA_CONCURRENTALLOCATORADAPTER
9#define INCLUDED_BDLMA_CONCURRENTALLOCATORADAPTER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlma_concurrentallocatoradapter bdlma_concurrentallocatoradapter
15/// @brief Provide a thread-enabled adapter for the allocator protocol.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlma
19/// @{
20/// @addtogroup bdlma_concurrentallocatoradapter
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlma_concurrentallocatoradapter-purpose"> Purpose</a>
25/// * <a href="#bdlma_concurrentallocatoradapter-classes"> Classes </a>
26/// * <a href="#bdlma_concurrentallocatoradapter-description"> Description </a>
27/// * <a href="#bdlma_concurrentallocatoradapter-thread-safety"> Thread Safety </a>
28/// * <a href="#bdlma_concurrentallocatoradapter-usage"> Usage </a>
29/// * <a href="#bdlma_concurrentallocatoradapter-example-1-basic-usage"> Example 1: Basic Usage </a>
30///
31/// # Purpose {#bdlma_concurrentallocatoradapter-purpose}
32/// Provide a thread-enabled adapter for the allocator protocol.
33///
34/// # Classes {#bdlma_concurrentallocatoradapter-classes}
35///
36/// - bdlma::ConcurrentAllocatorAdapter: thread-enabled allocator adapter
37///
38/// @see bslma_allocator, bdlma_concurrentmultipool
39///
40/// # Description {#bdlma_concurrentallocatoradapter-description}
41/// This component provides an adapter,
42/// `bdlma::ConcurrentAllocatorAdapter`, that implements the `bslma::Allocator`
43/// protocol and provides synchronization for operations on an allocator
44/// supplied at construction using a mutex also supplied at construction.
45/// @code
46/// ,-----------------------------------.
47/// ( bdlma::ConcurrentAllocatorAdapter )
48/// `-----------------------------------'
49/// | ctor/dtor
50/// V
51/// ,-----------------.
52/// ( bslma::Allocator )
53/// `-----------------'
54/// allocate
55/// deallocate
56/// @endcode
57///
58/// ## Thread Safety {#bdlma_concurrentallocatoradapter-thread-safety}
59///
60///
61/// `bdlma::ConcurrentAllocatorAdapter` is *thread-enabled*, meaning any
62/// operation on the same instance can be safely invoked from any thread.
63///
64/// ## Usage {#bdlma_concurrentallocatoradapter-usage}
65///
66///
67/// This section illustrates intended use of this component.
68///
69/// ### Example 1: Basic Usage {#bdlma_concurrentallocatoradapter-example-1-basic-usage}
70///
71///
72/// In the following usage example, we develop a simple `AddressBook` class
73/// containing two thread-enabled vectors of strings: one for names, the other
74/// for addresses. We use a `bdlma::ConcurrentAllocatorAdapter` to synchronize
75/// memory allocations across our two thread-enabled vectors. For the purpose
76/// of this discussion, we first define a simple thread-enabled vector:
77/// @code
78/// template <class TYPE>
79/// class ThreadEnabledVector {
80/// // This class defines a trivial thread-enabled vector.
81///
82/// // DATA
83/// mutable bslmt::Mutex d_mutex; // synchronize access
84/// bsl::vector<TYPE> d_elements; // underlying list of strings
85///
86/// // NOT IMPLEMENTED
87/// ThreadEnabledVector(const ThreadEnabledVector&);
88/// ThreadEnabledVector& operator=(const ThreadEnabledVector&);
89///
90/// public:
91/// // CREATORS
92/// ThreadEnabledVector(bslma::Allocator *basicAllocator = 0)
93/// // Create a thread-enabled vector. Optionally specify a
94/// // 'basicAllocator' used to supply memory. If 'basicAllocator' is
95/// // 0, the currently installed default allocator is used.
96/// : d_elements(basicAllocator)
97/// {
98/// }
99///
100/// ~ThreadEnabledVector() {}
101/// // Destroy this thread-enabled vector object.
102///
103/// // MANIPULATORS
104/// int pushBack(const TYPE& value)
105/// // Append the specified 'value' to this thread-enabled vector and
106/// // return the index of the new element.
107/// {
108/// bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex);
109/// d_elements.push_back(value);
110/// return static_cast<int>(d_elements.size()) - 1;
111/// }
112///
113/// void set(int index, const TYPE& value)
114/// // Set the element at the specified 'index' in this thread-enabled
115/// // vector to the specified 'value'. The behavior is undefined
116/// // unless '0 <= index < length()'.
117/// {
118/// bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex);
119/// d_elements[index] = value;
120/// }
121///
122/// // ACCESSORS
123/// TYPE element(int index) const
124/// // Return the value of the element at the specified 'index' in this
125/// // thread-enabled vector. Note that elements are returned *by*
126/// // *value* because references to elements managed by this container
127/// // may be invalidated by another thread.
128/// {
129/// bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex);
130/// return d_elements[index];
131/// }
132///
133/// int length() const
134/// // Return the number of elements in this thread-enabled vector.
135/// {
136/// bslmt::LockGuard<bslmt::Mutex> guard(&d_mutex);
137/// return static_cast<int>(d_elements.size());
138/// }
139/// };
140/// @endcode
141/// We use this thread-enabled vector to create a AddressBook class. However,
142/// we use the `bdlma::ConcurrentAllocatorAdapter` to prevent our two
143/// (thread-enabled) vectors from attempting synchronous memory allocations from
144/// our (potentially) non-thread safe `bslma::Allocator`. Note that we define a
145/// local class, `AddressBook_PrivateData`, in order to guarantee that
146/// `d_allocatorAdapter` and `d_mutex` are initialized before the thread-enabled
147/// vectors that depend on them:
148/// @code
149/// struct AddressBook_PrivateData {
150/// // This 'struct' contains a mutex and an allocator adapter. The
151/// // 'AddressBook' class will inherit from this structure, ensuring that
152/// // the mutex and adapter are initialized before other member variables
153/// // that depend on them.
154///
155/// private:
156/// // Not implemented:
157/// AddressBook_PrivateData(const AddressBook_PrivateData&);
158///
159/// public:
160/// bslmt::Mutex d_mutex; // synchronize allocator
161///
162/// bdlma::ConcurrentAllocatorAdapter
163/// d_allocatorAdapter; // adapter for allocator
164///
165/// AddressBook_PrivateData(bslma::Allocator *basicAllocator = 0)
166/// // Create a empty AddressBook private data object. Optionally
167/// // specify a 'basicAllocator' used to supply memory. If
168/// // 'basicAllocator' is 0, the currently installed default allocator
169/// // is used.
170/// : d_allocatorAdapter(&d_mutex, basicAllocator)
171/// {
172/// }
173/// };
174///
175/// class AddressBook : private AddressBook_PrivateData {
176/// // This 'class' defines a thread-enabled AddressBook containing vectors
177/// // of names and addresses. Note that this class uses private
178/// // inheritance to ensure that the allocator adapter and mutex are
179/// // initialized before the vectors of names and addresses.
180///
181/// // DATA
182/// ThreadEnabledVector<bsl::string> d_names; // list of names
183/// ThreadEnabledVector<bsl::string> d_addresses; // list of addresses
184///
185/// private:
186/// // Not implemented:
187/// AddressBook(const AddressBook&);
188///
189/// public:
190/// // CREATORS
191/// AddressBook(bslma::Allocator *basicAllocator = 0)
192/// // Create an empty AddressBook for storing names and addresses.
193/// // Optionally specify a 'basicAllocator' used to supply memory. If
194/// // 'basicAllocator' is 0, the currently installed default allocator
195/// // is used.
196/// : AddressBook_PrivateData(basicAllocator)
197/// , d_names(&d_allocatorAdapter)
198/// , d_addresses(&d_allocatorAdapter)
199/// {
200/// }
201///
202/// ~AddressBook()
203/// // Destroy this AddressBook.
204/// {
205/// }
206///
207/// // MANIPULATORS
208/// int addName(const bsl::string& name)
209/// // Add the specified 'name' to this AddressBook and return the
210/// // index of the newly-added name.
211/// {
212/// return d_names.pushBack(name);
213/// }
214///
215/// int addAddress(const bsl::string& address)
216/// // Add the specified 'address' to this AddressBook and return the
217/// // index of the newly-added address.
218/// {
219/// return d_addresses.pushBack(address);
220/// }
221///
222/// // ACCESSORS
223/// bsl::string name(int index) const
224/// // Return the value of the name at the specified 'index' in this
225/// // AddressBook.
226/// {
227/// return d_names.element(index);
228/// }
229///
230/// bsl::string address(int index) const
231/// // Return the value of the address at the specified 'index' in this
232/// // AddressBook.
233/// {
234/// return d_addresses.element(index);
235/// }
236///
237/// int numNames() const
238/// // Return the number of names in this AddressBook.
239/// {
240/// return d_names.length();
241/// }
242///
243/// int numAddresses() const
244/// // Return the number of addresses in this AddressBook.
245/// {
246/// return d_addresses.length();
247/// }
248/// };
249/// @endcode
250/// @}
251/** @} */
252/** @} */
253
254/** @addtogroup bdl
255 * @{
256 */
257/** @addtogroup bdlma
258 * @{
259 */
260/** @addtogroup bdlma_concurrentallocatoradapter
261 * @{
262 */
263
264#include <bdlscm_version.h>
265
266#include <bslma_allocator.h>
267#include <bslma_default.h>
268
269#include <bslmt_mutex.h>
270
271#include <bsls_keyword.h>
272#include <bsls_types.h>
273
274#include <bslmt_mutex.h>
275
276
277namespace bdlma {
278
279 // ================================
280 // class ConcurrentAllocatorAdapter
281 // ================================
282
283/// This class defines an implementation of the `bslma::Allocator` protocol
284/// that "decorates" (wraps) a concrete `bslma::Allocator` to ensure
285/// thread-safe access to the decorated allocator.
286///
287/// See @ref bdlma_concurrentallocatoradapter
289
290 // DATA
291 bslmt::Mutex *d_mutex_p; // synchronizer for operations on the
292 // allocator (held, not owned)
293
294 bslma::Allocator *d_allocator_p; // allocator (held, not owned)
295
296 // NOT IMPLEMENTED
299 public:
300 // CREATORS
301
302 /// Create a thread-enabled allocator adapter that uses the specified
303 /// `mutex` to synchronize access to the specified `basicAllocator`. If
304 /// `basicAllocator` is 0, the currently installed default allocator is
305 /// used.
307 bslma::Allocator *basicAllocator);
308
309 /// Destroy this thread-enabled allocator adapter.
311
312 // MANIPULATORS
313
314 /// Return a newly-allocated block of memory of (at least) the specified
315 /// `numBytes`. If `numBytes` is 0, a null pointer is returned with no
316 /// other effect. If this allocator cannot return the requested number
317 /// of bytes, then it will throw a `bsl::bad_alloc` exception in an
318 /// exception-enabled build, or else will abort the program in a
319 /// non-exception build. Note that the alignment of the address
320 /// returned conforms to the platform requirement for any object of the
321 /// `numBytes`.
323
324 /// Return the memory at the specified `address` back to this allocator.
325 /// If `address` is 0, this function has no effect. The behavior is
326 /// undefined unless `address` was allocated using this allocator and
327 /// has not since been deallocated.
329};
330
331// ============================================================================
332// INLINE DEFINITIONS
333// ============================================================================
334
335 // --------------------------------
336 // class ConcurrentAllocatorAdapter
337 // --------------------------------
338
339// CREATORS
340inline
342 bslmt::Mutex *mutex,
343 bslma::Allocator *basicAllocator)
344: d_mutex_p(mutex)
345, d_allocator_p(bslma::Default::allocator(basicAllocator))
346{
347}
348
349} // close package namespace
350
351
352#endif
353
354// ----------------------------------------------------------------------------
355// Copyright 2016 Bloomberg Finance L.P.
356//
357// Licensed under the Apache License, Version 2.0 (the "License");
358// you may not use this file except in compliance with the License.
359// You may obtain a copy of the License at
360//
361// http://www.apache.org/licenses/LICENSE-2.0
362//
363// Unless required by applicable law or agreed to in writing, software
364// distributed under the License is distributed on an "AS IS" BASIS,
365// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
366// See the License for the specific language governing permissions and
367// limitations under the License.
368// ----------------------------- END-OF-FILE ----------------------------------
369
370/** @} */
371/** @} */
372/** @} */
Definition bdlma_concurrentallocatoradapter.h:288
~ConcurrentAllocatorAdapter() BSLS_KEYWORD_OVERRIDE
Destroy this thread-enabled allocator adapter.
void * allocate(bsls::Types::size_type numBytes) BSLS_KEYWORD_OVERRIDE
void deallocate(void *address) BSLS_KEYWORD_OVERRIDE
Definition bslma_allocator.h:457
std::size_t size_type
Definition bslma_allocator.h:499
Definition bslmt_mutex.h:315
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition bdlma_alignedallocator.h:276
Definition balxml_encoderoptions.h:68
Definition bslmt_barrier.h:344
Definition bdlt_iso8601util.h:691