nlib
nn::nlib::LockFreeBroadcastQueue< T > Class Template Referencefinal

The specified number of listeners can obtain elements from the queue. After all the listeners have obtained elements, those elements are deleted from the queue. More...

#include "nn/nlib/LockFree.h"

Public Types

typedef UniquePtr< const T, empty_func > DequeueType
 The type for the argument of Dequeue().
 

Public Member Functions

errno_t Enqueue (const T *obj) noexcept
 Adds an element to the queue. This is thread-safe. More...
 
errno_t Dequeue (int32_t listener_id, DequeueType &obj) noexcept
 Specifies the listener and then reads an element from the queue. This is thread-safe when using a different listener_id. More...
 
size_t GetListenerCount () const noexcept
 Returns the number of listeners specified in Init(). This is thread-safe.
 
void SwapUnsafe (LockFreeBroadcastQueue &rhs) noexcept
 Swaps an object. This is not thread-safe.
 
Constructor, Destructor, and Initialization
 LockFreeBroadcastQueue () noexcept
 Instantiates the object with default parameters (default constructor).
 
 ~LockFreeBroadcastQueue () noexcept
 Destructor. More...
 
errno_t Init (size_t max_size, size_t listeners) noexcept
 Initializes the queue. This is not thread-safe. More...
 

Detailed Description

template<class T>
class nn::nlib::LockFreeBroadcastQueue< T >

The specified number of listeners can obtain elements from the queue. After all the listeners have obtained elements, those elements are deleted from the queue.

Template Parameters
TThe queue element type.
Description
Note that no objects that serve as the elements will be destroyed until all the listeners have obtained the elements. Sample code is provided below.
struct MyMessage { const char* text; };
const int kNumReceivers = 3;
errno_t e = queue.Init(128, kNumReceivers);
SUCCEED_IF(e == 0);
std::unique_ptr<MyMessage> obj;
const char* message_list[] = {
"Hello, this is the queue for broadcasting messages",
"The messages are shared among the listeners.",
"They are preserved until all the listeners read them.",
"They are to be deleted automatically.",
nullptr
};
for (auto& message : message_list) {
obj.reset(new (std::nothrow) MyMessage());
SUCCEED_IF(!!obj);
obj->text = message;
queue.Enqueue(obj.release());
}
std::thread th_list[kNumReceivers];
for (int i = 0; i < kNumReceivers; ++i) {
th_list[i] = std::thread([&](int listender_id) {
for (;;) {
while (queue.Dequeue(listender_id, ptr) != 0) { nlib_yield(); }
if (!ptr->text) break;
nlib_printf("thread %d receives '%s'\n", GetMyThreadId(), ptr->text);
}
}, i);
}
for (auto& th : th_list) { th.join(); }
/*
Output:
thread 20568 receives 'Hello, this is the queue for broadcasting messages'
thread 20568 receives 'The messages are shared among the listeners.'
thread 20516 receives 'Hello, this is the queue for broadcasting messages'
thread 20568 receives 'They are preserved until all the listeners read them.'
thread 20516 receives 'The messages are shared among the listeners.'
thread 20568 receives 'They are to be deleted automatically.'
thread 22760 receives 'Hello, this is the queue for broadcasting messages'
thread 20516 receives 'They are preserved until all the listeners read them.'
thread 22760 receives 'The messages are shared among the listeners.'
thread 20516 receives 'They are to be deleted automatically.'
thread 22760 receives 'They are preserved until all the listeners read them.'
thread 22760 receives 'They are to be deleted automatically.'
*/

Definition at line 739 of file LockFree.h.

Constructor & Destructor Documentation

◆ ~LockFreeBroadcastQueue()

template<class T>
nn::nlib::LockFreeBroadcastQueue< T >::~LockFreeBroadcastQueue ( )
inlinenoexcept

Destructor.

Description
Uses DestructorForLockFree to delete each of remaining elements, if any. If necessary, specialize a function template to perform necessary processing..

Definition at line 746 of file LockFree.h.

Member Function Documentation

◆ Dequeue()

template<class T>
nn::nlib::LockFreeBroadcastQueue< T >::Dequeue ( int32_t  listener_id,
DequeueType obj 
)
inlinenoexcept

Specifies the listener and then reads an element from the queue. This is thread-safe when using a different listener_id.

Parameters
[in]listener_idAn integer that is 0 or larger and less than the number of listeners specified in Init().
[out]objThe read element.
Return values
0Success.
EAGAINNo new element that can be read is available in the queue.
Description
The obtained elements are valid until Dequeue() is executed next time. Note that no element is deleted until Dequeue() for all listeners has completed.

Definition at line 761 of file LockFree.h.

◆ Enqueue()

template<class T>
nn::nlib::LockFreeBroadcastQueue< T >::Enqueue ( const T *  obj)
inlinenoexcept

Adds an element to the queue. This is thread-safe.

Parameters
[in]objThe element to be added to the queue.
Return values
0Success.
EAGAINThe queue is full.

Definition at line 757 of file LockFree.h.

◆ Init()

template<class T>
nn::nlib::LockFreeBroadcastQueue< T >::Init ( size_t  max_size,
size_t  listeners 
)
inlinenoexcept

Initializes the queue. This is not thread-safe.

Parameters
[in]max_sizeThe maximum number of elements that can be stored in the queue.
[in]listenersThe number of listeners.
Return values
0Success.
EINVALmax_size exceeds INT32_MAX.
ENOMEMMemory allocation has failed.

Definition at line 753 of file LockFree.h.


The documentation for this class was generated from the following files: