#include <posix.h>
Public Member Functions | |
posix_thread_fast_t () | |
Very cheap and fast default constructor. | |
virtual | ~posix_thread_fast_t () |
Stops the running thread. | |
void | cancel (void) |
As expected, cancels the thread. | |
void | create (posix_fun_ptr aFunc, void *aData) |
void | join (void) |
bool | exec_lock (void) |
Private Member Functions | |
void | operator= (const posix_thread_fast_t &) |
As usual, threads are not copiable nor assignable. | |
posix_thread_fast_t (const posix_thread_fast_t &) | |
void | init (void) |
A flag avoids useless threads creation. | |
Static Private Member Functions | |
static void | slv_loop (posix_thread_fast_t *aThis) |
Executed by the sub-thread. (slv=slave). | |
Private Attributes | |
posix_fun_ptr | _Func |
The function to execute. This should probably be atomic... | |
void * | _Data |
pthread_mutex_t | _Mtx |
pthread_cond_t | _cond_start |
bool | _NotInit |
pthread_t | _thread |
Reused several times. |
rpa::posix_thread_fast_t::posix_thread_fast_t | ( | const posix_thread_fast_t & | ) | [private] |
rpa::posix_thread_fast_t::posix_thread_fast_t | ( | ) |
Very cheap and fast default constructor.
The constructor cost is very small, because the internal real thread is cerated only when needed.
rpa::posix_thread_fast_t::~posix_thread_fast_t | ( | ) | [virtual] |
Stops the running thread.
Here, the thread waits for the condition to be set.
Here, the function is NULL.
void rpa::posix_thread_fast_t::cancel | ( | void | ) |
As expected, cancels the thread.
Must check that the thread is cancellable.
void rpa::posix_thread_fast_t::create | ( | posix_fun_ptr | aFunc, | |
void * | aData | |||
) |
Starts the thread. Theoretically, we should first lock the mutex. But, by construction, the thread must be waiting for a condition. So, we save a lock+unlock. This described behaviour is standard.
bool rpa::posix_thread_fast_t::exec_lock | ( | void | ) |
Tries to execute directly the function of the thread if this thread did not start yet - thus saving a task switch, and saving time if this thread takes time to start. Returns true if the function is executed.
Because of this, prevents another execution.
void rpa::posix_thread_fast_t::init | ( | void | ) | [private] |
A flag avoids useless threads creation.
We must wait until the main thread is in the cond_wait, otherwise it does not work.
The thread cannot signal the condition before we wait, because it first waits for the mutex. We use the word 'notify' because it allows to use Boost's condition.
Here, we are sure that the thread is started. We left the cond_wait, not only because the condition is signaled by the sub-thread, but also because the mutex is unlocked.
This unlocks now the mutex, otherwise the sub-thread could not start.
void rpa::posix_thread_fast_t::join | ( | void | ) |
Is called by another thread. To implement this, we simply wait until the thread has finished its job.
If here, it means that the function is already executed by the thread.
Here, the thread did not start yet. So, we execute the function in the current thread. The sub-thread cannot execute in the mean time because the mutex is locked.
This prevents the sub-thread from executing.
void rpa::posix_thread_fast_t::operator= | ( | const posix_thread_fast_t & | ) | [private] |
As usual, threads are not copiable nor assignable.
void rpa::posix_thread_fast_t::slv_loop | ( | posix_thread_fast_t * | aThis | ) | [static, private] |
Executed by the sub-thread. (slv=slave).
This is the actual function executed by the thread. It waits until is new function pointer is shceduled for execution by the user.
We must wait until the main thread enters the pthread_cond_wait, which will unlock the mutex.
The mutex is still locked, and the main thread has to stay into the cond_wait, although the condition is signaled.
When the sub-thread was running, maybe the function was executed by the main thread ?
Or, we request the end of the thread.
This tells that the end is near, and requested.
pthread_cond_t rpa::posix_thread_fast_t::_cond_start [private] |
void* rpa::posix_thread_fast_t::_Data [private] |
posix_fun_ptr rpa::posix_thread_fast_t::_Func [private] |
The function to execute. This should probably be atomic...
pthread_mutex_t rpa::posix_thread_fast_t::_Mtx [private] |
bool rpa::posix_thread_fast_t::_NotInit [private] |
False when created. So, the real POSIX thread is created only when the first function is scheduled by the calling program for execution.
pthread_t rpa::posix_thread_fast_t::_thread [private] |
Reused several times.