Dv::Thread::Thread Class Reference

Posix thread class. More...

#include <thread.h>

Inheritance diagram for Dv::Thread::Thread:
Inheritance graph
[legend]
Collaboration diagram for Dv::Thread::Thread:
Collaboration graph
[legend]

List of all members.

Public Types

enum  errors { BAD_EXCEPTION = -1, DEFAULT_MAIN = -2 }

Public Member Functions

 Thread (bool delete_after_main=false, unsigned int min_debug_level=0, Debugable *debug_master=0)
 Constructor.
virtual ~Thread ()
 Destructor.
int start ()
 Start up thread, executing the main function of this Thread object.
virtual int main ()
 Main function of thread.
int join ()
 Wait for a non-detached thread to finish.
void wait ()
 Wait for a thread to stop running.
virtual void kill (int signal=SIGUSR1)
 Kill a thread.
int status () const
 Return exit status of this thread.
pthread_t id () const
 Return posix thread id of this thread.
std::string sid () const
 String representation of thread id of this thread.
int detach () const
 Detach this thread.
bool is_self () const
 Is this thread the currently running thread? This function is 'delete-after-main safe'.
bool running () const
 Is this thread running?
pthread_t joined_by () const
 Has this thread been joined?
pthread_t detached_by () const
 Has this thread been detached?

Static Public Member Functions

static Threadself ()
 Return pointer to currently running thread or 0.
static pthread_t self_id () throw ()
 Return id (pthread_t ) of the currently running thread.
static void sleep (size_t millisecs)
 Safe version of sleep which uses a 'dummy' Monitor::wait.
static size_t wait_for_all ()
 Wait for all threads to have finished.
static int sig_set_handler (int signal=SIGUSR1, void(*handler)(int)=Dv::Thread::Thread::sig_handler, int sigaction_flags=0)
 Set signal handler for all threads (in this process).
static void sig_handler (int signal)
 Default signal handler.
static int sig_block (int signal, bool unblock=false)
 Block or unblock a signal for the currently running thread.
static int sig_unblock (int signal)
 Unblock a signal for the currently running thread.

Protected Member Functions

void exit (int status)
 Finish this thread, with status.
int killed () const

Protected Attributes

volatile sig_atomic_t killed_
 Set by default signal handler.

Private Member Functions

bool delete_after_main () const
 Will this thread object be deleted after Thread::main() has completed?
bool at_end () const
 Thread (const Thread &)
 Forbid cctor.
Threadoperator= (const Thread &)
 Forbid assignment.
void set_status (int status)
 Set the exit status of this thread.

Static Private Member Functions

static void * run_thread (Dv::Thread::Thread *t)
 Startup function wrapping around t->main, passed to pthread_create.

Private Attributes

pthread_t id_
 Posix thread id.
pthread_attr_t attributes_
 Posix thread attributes.
int exit_status_
 Exit status of this thread.
bool delete_after_main_
 Should this object be deleted after Thread::main has completed?
pthread_t joiner_
 pthread_t id of thread that has joined this thread or 0
pthread_t detacher_
 pthread_t id of thread that has detached this thread or 0
int cancel_state_
 we disable this
Barrier barrier_
 private barrier, used to synchronize parent and new thread
bool at_end_
 set at end of Dv::Thread::Thread::run_thread

Friends

class Threads
 Singleton class that keeps the relation between Dv::Thread::Thread objects and corresponding pthread_t objects (i.e.
int start (Thread &t)

Detailed Description

Posix thread class.

See also:
Dv::Thread::Monitor

Member Enumeration Documentation

Enumerator:
BAD_EXCEPTION 
DEFAULT_MAIN 

Constructor & Destructor Documentation

Dv::Thread::Thread::Thread ( bool  delete_after_main = false,
unsigned int  min_debug_level = 0,
Debugable debug_master = 0 
)

Constructor.

Note that there are 2 types of debug: for internal debugging of the dvthread library: use Dv::Thread::thread_debug . For debugging of derived classes write e.g. to t.log().

Parameters:
delete_after_main if true, delete(t) will be executed after t->main() has completed. Since joining such a thread may not be possible (the Dv::Thread::Thread object may have been auto-deleted by the time another thread wants to join it), such threads are automatically detached by Dv::Thread::Thread::start.
min_debug_level if a debug_master is connected, statements such as

   log(4) << FUNCTION_S << ": trouble" << std::endl;

will only be executed if the master's level is at least min_debug_level

debug_master from where debug info will be taken
Warning:
to not set the delete_after_main parameter unless the thread was created using new. Since such threads may finish (and be destroyed) anytime, it makes no sense to refer to them after they have started. Thus a typical usage would be
   new Thread(true,..)->start();
See also:
Dv::DebugSlave
Dv::Thread::Thread::delete_after_main
Dv::DebugSlave
virtual Dv::Thread::Thread::~Thread (  )  [virtual]

Destructor.

If this function is called by the thread itself, and it has not been joined nor detached, the thread will first detach itself. Otherwise, it will throw an exception.

Exceptions:
std::logic_error if the thread was neither joined nor detached unless the destructor was called by the thread itself, in which case an automatic detach will be done during the destruction.
std::logic_error iff the executing thread is not this thread and this thread was not yet detached or joined.

Reimplemented in Dv::Thread::Pool::Thread.

Dv::Thread::Thread::Thread ( const Thread  )  [private]

Forbid cctor.


Member Function Documentation

int Dv::Thread::Thread::start (  ) 

Start up thread, executing the main function of this Thread object.

Upon return, the new thread has actually already received some CPU time (actually, it may already have finished).

Returns:
0 iff ok
errno iff pthread_create failed.
Exceptions:
runtime_error if thread is already running.
Warning:
Upon failure, the Thread subject is not deleted, not even if the thread was created with delete_after_main=true,
See also:
Dv::Thread::Thread::running

Referenced by Dv::Thread::ActorPool< HandlerFactory >::Actor::Actor(), Dv::Thread::Actor< Handler >::Actor(), and Dv::Thread::ActorPool< HandlerFactory >::ActorPool().

virtual int Dv::Thread::Thread::main (  )  [virtual]

Main function of thread.

Returns:
the value to keep in status Note that this function should not throw any exceptions except integers. The library will catch any exception e that is thrown erroneously, print e.what() on cerr and return an exit status of BAD_EXCEPTION.
See also:
Dv::Thread::Thread::start
Dv::Thread::Thread::BAD_EXCEPTION
Dv::Thread::Thread::exit
Dv::Thread::Thread::set_status

Reimplemented in Dv::Thread::Actor< Handler >, Dv::Thread::ActorPool< HandlerFactory >::Actor, Dv::Thread::ActorPool< HandlerFactory >, Dv::Thread::Pool::Thread, Reader, and Writer.

int Dv::Thread::Thread::join (  ) 

Wait for a non-detached thread to finish.

If the argument thread is not detached, it will be joined using pthread_join. If the thread never started, the return value will be 0.

Warning:
Do not use this on threads that were created with the delete_after_main function. Besides being automatically detached, such threads may have been deleted already at the time of the call to join, making the references to members in the code of Dv::Thread::Thread::join unsafe.
Returns:
0 iff ok, see manpage for pthread_join for other possibities.
See also:
Dv::Thread::Thread::detach
Dv::Thread::Thread::detached_by
Dv::Thread::Thread::running
 MyThread t;
 cout << "starting t" << endl;
 t.start();
 cout << "waiting for t to finish" << endl;
 join(t);
Exceptions:
std::logic_error if, by chance, the system correctly detects that the thread was detached and/or created using delete_after_main.
See also:
Dv::Thread::Thread::running
Dv::Thread::Thread::wait
void Dv::Thread::Thread::wait (  ) 

Wait for a thread to stop running.

This works even for detached threads or threads that have been deleted (e.g. threads that were created using the delete_after_main option).

See also:
Dv::Thread::Thread::join

Reimplemented in Dv::Thread::Pool::Thread.

Referenced by Dv::Thread::ActorPool< HandlerFactory >::~ActorPool().

virtual void Dv::Thread::Thread::kill ( int  signal = SIGUSR1  )  [virtual]

Kill a thread.

By default, this function simply sets killed_. If the thread is no longer running, this function has no effect. This function is 'delete-after-main' safe.

Returns:
0 iff the operation succeeded
Exceptions:
std::logic_error iff a thread tries to kill itself
See also:
Dv::Thread::Thread::killed
Dv::Thread::Thread::sig_set_handler

Referenced by Dv::Thread::ActorPool< HandlerFactory >::~ActorPool().

int Dv::Thread::Thread::status (  )  const [inline]

Return exit status of this thread.

Warning:
this function should not be used on 'delete-after-main' threads.
Returns:
exit status of thread.

References exit_status_.

pthread_t Dv::Thread::Thread::id (  )  const [inline]

Return posix thread id of this thread.

Warning:
this function should not be used on 'delete-after-main' threads.
Returns:
Posix thread id.

References id_.

Referenced by Writer::main(), and Reader::main().

std::string Dv::Thread::Thread::sid (  )  const

String representation of thread id of this thread.

Warning:
this function should not be used on 'delete-after-main' threads.
Returns:
string representation of the id of this thread
int Dv::Thread::Thread::detach (  )  const

Detach this thread.

Threads are created as ``joinable'', this function makes this impossible. It also ensures that all resources are freed when the thread exits.

Warning:
this function should not be used on 'delete-after-main' threads.
To avoid a memory leak, a thread must be joined or detached.
Returns:
0 if successful
status returned by pthread_detach otherwise
Warning:
Detaching a thread that is not yet started will return EINVAL
See also:
Dv::Thread::Thread::join
Dv::Thread::Thread::detached_by

Referenced by Dv::Thread::ActorPool< HandlerFactory >::main().

bool Dv::Thread::Thread::is_self (  )  const

Is this thread the currently running thread? This function is 'delete-after-main safe'.

Returns:
true iff this thread is the currently running thread
false otherwise
bool Dv::Thread::Thread::running (  )  const

Is this thread running?

Warning:
if the thread was created using delete_after_main, it may be that 'this' is no longer valid. However, this function should still work since it does not touch any members of Dv::Thread::Thread.
Returns:
true iff this thread has been started using Dv::Thread::Thread::start, it has already been in the 'running' state at least once and it has not yet finished executing its Dv::Thread::Thread::main function.
false otherwise
static Thread* Dv::Thread::Thread::self (  )  [static]

Return pointer to currently running thread or 0.

Returns:
pointer to currently running thread,
0 if the thread was not made by this library.
static pthread_t Dv::Thread::Thread::self_id (  )  throw () [inline, static]

Return id (pthread_t ) of the currently running thread.

This works for any thread; it is actually just a call to pthread_self.

Returns:
id of currently running thread.

Referenced by Dv::Thread::MailBox< MessageReply >::put().

static void Dv::Thread::Thread::sleep ( size_t  millisecs  )  [static]

Safe version of sleep which uses a 'dummy' Monitor::wait.

Examples:
test-pool.C.
pthread_t Dv::Thread::Thread::joined_by (  )  const [inline]

Has this thread been joined?

Returns:
pthread_t id of thread that has joined this thread.
0 if no thread has joined this thread yet
Warning:
this function should not be used on 'delete-after-main' threads.
See also:
Dv::Thread::Thread::join

References joiner_.

pthread_t Dv::Thread::Thread::detached_by (  )  const [inline]

Has this thread been detached?

Returns:
pthread_t id of thread that has detached this thread.
0 if no thread has detached this thread yet
Warning:
this function should not be used on 'delete-after-main' threads.
See also:
Dv::Thread::Thread::detach

References detacher_.

static size_t Dv::Thread::Thread::wait_for_all (  )  [static]

Wait for all threads to have finished.

Warning:
there should be no possibility for threads to be created (in another running thread) while this function is called. Typically, this function is called at the end of the program by the only thread-creating (main) thread.
this function does not join any thread, it simply observes the set of running Dv::Thread::Thread objects until it is empty.
Returns:
the number of threads waited for
static int Dv::Thread::Thread::sig_set_handler ( int  signal = SIGUSR1,
void(*)(int)  handler = Dv::Thread::Thread::sig_handler,
int  sigaction_flags = 0 
) [static]

Set signal handler for all threads (in this process).

The handling of OS signals in C++ (and multi-threaded applications) is problematic:

  • A conceptually nice idea of translating a signal to an exception (i.e. let the handler function throw an exception) almost never works, see the example file test-signal-exception.C included with the distribution.
  • Moreover, there are strong restrictions on what can be done in a signal handler.

The present implementation only provides a bare-bones minimal solution which seems to work reasonably well:

This implementation uses sigact.

Parameters:
signal for which handler is set
handler to call if signal s is received
sigaction_flags passed as sa_mask in sigaction, see the man page for sigaction(2).
Returns:
0 if all went well
-1 if sigemptyset failed
-2 if sigaddset failed
-3 if sigaction failed
Warning:
Uses pthread_sigmask, not sigprocmask
See also:
Dv::Thread::Thread::sig_set_handler
Dv::Thread::Thread::sig_handler
Dv::Thread::Thread::sig_block
Dv::Thread::Thread::sig_unblock
Dv::Thread::Thread::kill
static void Dv::Thread::Thread::sig_handler ( int  signal  )  [static]

Default signal handler.

This handler will set the killed_ data member for the thread receiving the signal.

Parameters:
signal used by pthread_kill
See also:
Dv::Thread::Thread::sig_set_handler
Dv::Thread::Thread::sig_handler
Dv::Thread::Thread::sig_block
Dv::Thread::Thread::sig_unblock
Dv::Thread::Thread::kill
static int Dv::Thread::Thread::sig_block ( int  signal,
bool  unblock = false 
) [static]

Block or unblock a signal for the currently running thread.

This implementation uses pthread_sigmask.

Parameters:
signal to (un)block
unblock if true, unblock instead of block the signal
Returns:
0 if all went well
-1 if sigemptyset failed
-2 if sigaddset failed
-3 if pthread_sigmask failed
See also:
Dv::Thread::Thread::sig_set_handler
Dv::Thread::Thread::sig_handler
Dv::Thread::Thread::sig_block
Dv::Thread::Thread::sig_unblock
Dv::Thread::Thread::kill
static int Dv::Thread::Thread::sig_unblock ( int  signal  )  [static]

Unblock a signal for the currently running thread.

This implementation uses pthread_sigmask.

Parameters:
signal to unblock
Returns:
0 if all went well
-1 if sigemptyset failed
-2 if sigaddset failed
-3 if pthread_sigmask failed
See also:
Dv::Thread::Thread::sig_set_handler
Dv::Thread::Thread::sig_handler
Dv::Thread::Thread::sig_block
Dv::Thread::Thread::sig_unblock
Dv::Thread::Thread::kill
void Dv::Thread::Thread::exit ( int  status  )  [protected]

Finish this thread, with status.

This function is 'delete-after-main safe'.

Parameters:
status to return.
Warning:
This function must be called by the running thread itself, i.e. this==DvThread::Thread::self() must hold
This is implemented by throwing the status integer as an exception. Hence if your code catches integers, as in
 try {
    exit(3);
 }
 catch (integer e) {
 }
the thread will not exit.

The implementation of this function was changed between versions 0.4 and 0.5 because the previous implementation, which used pthread_exit, gave problems on systems with the nptl thread implementation.

Exceptions:
std::logic_error if the calling thread is not this thread
See also:
Dv::Thread::Thread::main
int Dv::Thread::Thread::killed (  )  const [inline, protected]
bool Dv::Thread::Thread::delete_after_main (  )  const [inline, private]

Will this thread object be deleted after Thread::main() has completed?

Warning:
this function should not be used on 'delete-after-main' threads.
Returns:
true iff this object will be deleted after Thread::main() finished.

References delete_after_main_.

bool Dv::Thread::Thread::at_end (  )  const [inline, private]

References at_end_.

Thread& Dv::Thread::Thread::operator= ( const Thread  )  [private]

Forbid assignment.

static void* Dv::Thread::Thread::run_thread ( Dv::Thread::Thread t  )  [static, private]

Startup function wrapping around t->main, passed to pthread_create.

Parameters:
t thread to start running
void Dv::Thread::Thread::set_status ( int  status  )  [inline, private]

Set the exit status of this thread.

Parameters:
status to set as exit status, normally result of main()

References exit_status_.


Friends And Related Function Documentation

friend class Threads [friend]

Singleton class that keeps the relation between Dv::Thread::Thread objects and corresponding pthread_t objects (i.e.

thread identifiers in the pthread library).

int start ( Thread t  )  [friend]

Member Data Documentation

volatile sig_atomic_t Dv::Thread::Thread::killed_ [protected]

Set by default signal handler.

See also:
Dv::Thread::Thread::kill
Dv::Thread::Thread::killed

Referenced by killed().

pthread_t Dv::Thread::Thread::id_ [private]

Posix thread id.

Referenced by id().

pthread_attr_t Dv::Thread::Thread::attributes_ [private]

Posix thread attributes.

Exit status of this thread.

Referenced by set_status(), and status().

Should this object be deleted after Thread::main has completed?

Referenced by delete_after_main().

pthread_t Dv::Thread::Thread::joiner_ [private]

pthread_t id of thread that has joined this thread or 0

Referenced by joined_by().

pthread_t Dv::Thread::Thread::detacher_ [private]

pthread_t id of thread that has detached this thread or 0

Referenced by detached_by().

we disable this

private barrier, used to synchronize parent and new thread

set at end of Dv::Thread::Thread::run_thread

Referenced by at_end().


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

dvthread-0.13.4 [11 December, 2009]