BDE 4.14.0 Production release
|
Provide thread-enabled state management for a fixed-size queue.
This component implements a lock-free mechanism for managing the indices of a circular buffer of elements to facilitate the implementation of a fixed-size thread-enabled single-ended queue. A bdlcc::FixedQueueIndexManager
is supplied the size of a circular buffer on construction, and provides the methods to reserve indices for enqueing and dequeing elements in that buffer. The actual buffer is held in some other (external) data structure managed by the user of this component.
This component is not itself a general-purpose queue data structure. For example, no user data of any kind is stored in this data structure (it is not a queue of integers), and successful invocation of certain methods (reservePopIndex
, reservePushIndex
) obligates the caller to invoke a corresponding method (commitPopIndex
, commitPushIndex
respectively); otherwise, other threads may "spin" indefinitely with severe performance consequences.
bdlcc::FixedQueueIndexManager
is fully thread-safe, meaning that all non-creator operations on an object can be safely invoked simultaneously from multiple threads.
All methods of the bdlcc::FixedQueueIndexManager
provide a no-throw exception guarantee, except for the constructor, which is exception neutral.
This section illustrates intended use of this component.
In the following example we create a simple thread-safe queue of integers using a bdlcc::FixedQueueIndexManager
to synchronize the queue operations.
We start by declaring the data members of an IntegerQueue
, a vector of integers, to hold the values in the queue, and an index manager to ensure thread-safe access to the indices of the vector:
Then, we declare the methods of an integer queue:
Next, we define the constructor, which initializes both the index manager and vector with the supplied capacity:
Now, we define tryPushBack
and tryPopFront
, which use the index manager to reserve an index in the vector, operate on that index, and then commit that index back to the index manager:
Notice that because none of these operations allocate memory, we do not need to add code to ensure exception safety.
Then, we define the accessors to the integer queue:
Finally, we create an IntegerQueue
, and push and pop a couple of elements into the queue: