Lumiera  0.pre.03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Thread Class Reference

#include "backend/thread-wrapper.hpp"


A thin convenience wrapper for dealing with threads, as implemented by the threadpool in the backend (based on pthread).

Using this wrapper...

  • helps with passing data to the function executed in the new thread
  • allows to bind to various kinds of functions including member functions The new thread starts immediately within the ctor; after returning, the new thread has already copied the arguments and indeed actively started to run.

Joining, cancellation and memory management

In the basic version (class Thread), the created thread is completely detached and not further controllable. There is no way to find out its execution state, wait on termination or even cancel it. Client code needs to implement such facilities explicitly, if needed. Care has to be taken with memory management, as there are no guarantees beyond the existence of the arguments bound into the operation functor. If the operation in the started thread needs additional storage, it has to manage it actively.

There is an extended version (class ThreadJoinable) to allow at least to wait on the started thread's termination (joining). Building on this it is possible to create a self-contained "thread in an object"; the dtor of such an class must join to prevent pulling away member variables the thread function will continue to use.

failures in the thread function

The operation started in the new thread is protected by a top-level catch block. Error states or caught exceptions can be propagated through the lumiera_error state flag, when using ThreadJoinable::join(). By invoking join().maybeThrow() on a join-able thread, exceptions can be propagated.

any errorstate or caught exception detected on termination of a standard async Thread is considered a violation of policy and will result in emergency shutdown of the whole application.

synchronisation barriers

Lumiera threads provide a low-level synchronisation mechanism, which is used to secure the hand-over of additional arguments to the thread function. It can be used by client code, but care has to be taken to avoid getting out of sync. When invoking the sync and syncPoint functions, the caller will block until the counterpart has also invoked the corresponding function. If this doesn't happen, you'll block forever.

Definition at line 110 of file thread-wrapper.hpp.

Public Member Functions

template<class FUN >
 Thread (Literal purpose, FUN &&operation, NoBugFlag logging_flag=&NOBUG_FLAG(thread))
 Create a new thread to execute the given operation. More...
bool isValid () const
void sync ()
 Synchronisation barrier. More...

Static Public Member Functions

static void syncPoint ()
 counterpart of the synchronisation barrier, to be called from within the thread to be synchronised. More...

Protected Member Functions

 Thread ()
bool invokedWithinThread () const
 determine if the currently executing code runs within this thread More...
template<class FUN >
void launchThread (Literal purpose, FUN &&operation, NoBugFlag logging_flag, uint additionalFlags=0)

Protected Attributes

LumieraThread threadHandle_

Static Private Member Functions

template<class FUN >
static FUN && forwardInitialiser (void *rawPtr) noexcept
template<class FUN >
static void threadMain (void *arg)

Additional Inherited Members

- Private Member Functions inherited from MoveOnly
 MoveOnly ()=default
 MoveOnly (MoveOnly &&)=default
 MoveOnly (MoveOnly const &)=delete
 ~MoveOnly ()=default
MoveOnlyoperator= (MoveOnly &&)=delete
MoveOnlyoperator= (MoveOnly const &)=delete

Constructor & Destructor Documentation

Thread ( )

derived classes may create an inactive thread

Definition at line 155 of file thread-wrapper.hpp.

Thread ( Literal  purpose,
FUN &&  operation,
NoBugFlag  logging_flag = &NOBUG_FLAG(thread) 

Create a new thread to execute the given operation.

The new thread starts up synchronously, can't be cancelled and it can't be joined.

purposefixed char string used to denote the thread for diagnostics
logging_flagNoBug flag to receive diagnostics regarding the new thread
operationa functor holding the code to execute within the new thread. Any function-like entity with signature void(void) is acceptable.
The operation functor will be forwarded to create a copy residing on the stack of the new thread; thus it can be transient, however anything referred through a lambda closure here must stay alive until the new thread terminates.

Definition at line 196 of file thread-wrapper.hpp.

Member Function Documentation

static FUN&& forwardInitialiser ( void *  rawPtr)

perfect forwarding through a C-style void*

Definition at line 116 of file thread-wrapper.hpp.

static void threadMain ( void *  arg)

Definition at line 126 of file thread-wrapper.hpp.

References lumiera_error_peek(), LUMIERA_ERROR_SET, LUMIERA_ERROR_SET_ALERT, lumiera_thread_sync(), and Thread::sync().

+ Here is the call graph for this function:

void launchThread ( Literal  purpose,
FUN &&  operation,
NoBugFlag  logging_flag,
uint  additionalFlags = 0 

use the Lumiera thread manager to start a new thread and hand over the operation

Definition at line 161 of file thread-wrapper.hpp.

References Literal::c(), lumiera_error(), lumiera_thread_run(), and lumiera_thread_sync_other().

+ Here is the call graph for this function:

bool isValid ( ) const
by design there is no possibility to find out just based on the thread handle if some thread is alive. We define our own accounting here based on the internals of the thread wrapper. This will break down, if you mix uses of the C++ wrapper with the raw C functions.

Definition at line 209 of file thread-wrapper.hpp.

References Thread::threadHandle_.

Referenced by Thread::invokedWithinThread(), ThreadJoinable::join(), and Thread::sync().

+ Here is the caller graph for this function:

void sync ( )

Synchronisation barrier.

In the function executing in this thread needs to be a corresponding Thread::syncPoint() call. Blocking until both the caller and the thread have reached the barrier.

Definition at line 220 of file thread-wrapper.hpp.

References Thread::isValid(), lumiera_thread_sync_other(), and lumiera::throwOnError().

Referenced by DispatcherLoop::activateCommandProecssing(), DispatcherLoop::clear(), CallQueue_test::Worker::countConsumerCall(), DispatcherLoop::deactivateCommandProecssing(), DispatcherLoop::enqueue(), DispatcherLoop::processCommands(), DispatcherLoop::requestStop(), DispatcherLoop::size(), Thread::threadMain(), and CallQueue_test::verify_ThreadSafety().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void syncPoint ( )

counterpart of the synchronisation barrier, to be called from within the thread to be synchronised.

Will block until both this thread and the outward partner reached the barrier.

blocks on the current thread's condition var

Definition at line 233 of file thread-wrapper.hpp.

References lumiera_thread_sync().

Referenced by DispatcherLoop::runSessionThread(), and CallQueue_test::Worker::Worker().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool invokedWithinThread ( ) const

determine if the currently executing code runs within this thread

Definition at line 241 of file thread-wrapper.hpp.

References Thread::isValid(), lumiera_thread_self(), and Thread::threadHandle_.

Referenced by DispatcherLoop::stateIsSynched().

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

LumieraThread threadHandle_

Definition at line 152 of file thread-wrapper.hpp.

Referenced by Thread::invokedWithinThread(), and Thread::isValid().

+ Inheritance diagram for Thread:
+ Collaboration diagram for Thread:

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