c++-gtk-utils
Public Member Functions | Static Public Member Functions | List of all members
Cgu::Thread::Thread Class Reference

A class representing a pthread thread. More...

#include <c++-gtk-utils/thread.h>

Public Member Functions

void cancel ()
 
void join ()
 
void detach ()
 
bool is_caller ()
 

Static Public Member Functions

static std::auto_ptr< Cgu::Thread::Threadstart (const Cgu::Callback::Callback *cb, bool joinable)
 

Detailed Description

A class representing a pthread thread.

See also
Thread::Mutex Thread::Mutex::Lock Thread::Cond Thread::Future Thread::JoinableHandle

The Thread class encapsulates a pthread thread. It can start, join and cancel a thread.

Note
The Thread class, and the other thread related classes provided by this library such as Mutex, RecMutex, RWLock, CancelBlock and Cond, can be used interchangeably with (and mixed with) GThread objects and functions, and with GMutex, GRecMutex, GRWLock, GCond and similar, as they all use pthreads underneath on POSIX and other unix-like OSes. The main feature available with this thread implementation and not GThreads is thread cancellation, the mutex scoped locking classes Thread::Mutex::Lock and Thread::RecMutex::Lock, the joinable thread scoped management class Thread::JoinableHandle and the Thread::Future class (abstracting thread functions which provide a result). There is no need from the perspective of this class to call g_thread_init() before Cgu::Thread::Thread::start() is called, but prior to glib version 2.32 glib itself is not thread-safe without g_thread_init(), so where this class is used with glib < 2.32, g_thread_init() should be called at program initialization.

See Writing multi-threaded programs using c++-gtk-utils for particulars about GTK+ thread safety.

Member Function Documentation

◆ cancel()

void Cgu::Thread::Thread::cancel ( )
inline

Cancels the thread represented by this Thread object. It can be called by any thread. The effect is undefined if the thread represented by this Thread object has both (a) already terminated and (b) been detached or had a call to join() made for it. Accordingly, if the user is not able to establish from the program logic whether the thread has terminated, the thread must be created as joinable and cancel() must not be called after a call to detach() has been made or a call to join() has returned. A Thread::JoinableHandle object can used to ensure this. It does not throw.

Note
1. Use this method with care - sometimes its use is unavoidable but destructors for local objects may not be called if a thread exits by virtue of a call to cancel() (that depends on the implementation). Most modern commercial unixes, and recent linux/BSD distributions based on NPTL, will unwind the stack and call destructors on thread cancellation by means of a pseudo-exception, but older distributions relying on the former linuxthreads implementation will not. Therefore for maximum portability only have plain data structures/built-in types in existence in local scope when it occurs and if there is anything in free store to be released implement clean-ups with pthread_cleanup_push()/pthread_cleanup_pop(). This should be controlled with pthread_setcancelstate() and/or the CancelBlock class to choose the cancellation point.
2. When using thread cancellation, do not allow a cancellation pseudo-exception to propagate through a function with an exception specification, as the cancellation pseudo-exception may be incompatible with the specification and std::unexpected may be called.
See also
Cgu::Thread::Exit

◆ detach()

void Cgu::Thread::Thread::detach ( )
inline

Detaches the thread represented by this Thread object where it is joinable, so as to make it unjoinable. The effect is undefined if the thread is already unjoinable (a Thread::JoinableHandle object will however give a defined result in such cases for threads originally started as joinable). It does not throw.

◆ is_caller()

bool Cgu::Thread::Thread::is_caller ( )
inline

Specifies whether the calling thread is the same thread as is represented by this Thread object. The effect is undefined if the thread represented by this Thread object has both (a) already terminated and (b) been detached or had a call to join() made for it. Accordingly, if the user is not able to establish from the program logic whether the thread has terminated, the thread must be created as joinable and is_caller() must not be called after a call to detach() has been made or a call to join() has returned. A Thread::JoinableHandle object can used to ensure this. This method does not throw.

Returns
Returns true if the caller is in the thread represented by this Thread object.

◆ join()

void Cgu::Thread::Thread::join ( )
inline

Joins the thread represented by this Thread object (that is, waits for it to terminate). It can only be called by one thread, which can be any thread other than the one represented by this Thread object. The result is undefined if the thread represented by this Thread object is or was detached or join() has already been called for it (a Thread::JoinableHandle object will however give a defined result in such cases for threads originally started as joinable). It does not throw.

◆ start()

static std::auto_ptr<Cgu::Thread::Thread> Cgu::Thread::Thread::start ( const Cgu::Callback::Callback cb,
bool  joinable 
)
static

Starts a new thread. It can be called by any thread.

Parameters
cbA callback object (created by Callback::make() or Callback::make_ref()) encapsulating the function to be executed by the new thread. The Thread object returned by this function will take ownership of the callback: it will automatically be deleted either by the new thread when it has finished with it, or by this method in the calling thread if the attempt to start a new thread fails (including if std::bad_alloc is thrown).
joinableWhether the join() method may be called in relation to the new thread.
Returns
A Thread object representing the new thread which has been started, held by a std::auto_ptr object as it has single ownership semantics. The std::auto_ptr object will be empty (that is std::auto_ptr<Cgu::Thread::Thread>::get() will return 0) if the thread did not start correctly, which would mean that memory is exhausted, the pthread thread limit has been reached or pthread has run out of other resources to start new threads.
Exceptions
std::bad_allocThis method might throw std::bad_alloc if memory is exhausted and the system throws in that case. (This exception will not be thrown if the library has been installed using the --with-glib-memory-slices-no-compat configuration option: instead glib will terminate the program if it is unable to obtain memory from the operating system.) If this exception is thrown, the thread will not have started.
Note
1. The thread will keep running even if the return value of start() goes out of scope (but it will no longer be possible to call any of the methods in this class for it, which is fine if the thread is not started as joinable and it is not intended to cancel it).
2. If the thread is started with the joinable attribute, the user must subsequently either call the join() or the detach() method, as otherwise a resource leak may occur (the destructor of this class does not call detach() automatically). Alternatively, the return value of this method can be passed to a Thread::JoinableHandle object which will do this automatically in the Thread::JoinableHandle object's destructor.
3. Any Thread::Exit exception thrown from the function executed by the new thread will be caught and consumed. The thread will safely terminate and unwind the stack in so doing.
4. If any uncaught exception other than Thread::Exit is allowed to propagate from the initial function executed by the new thread, the exception is not consumed (NPTL's forced stack unwinding on cancellation does not permit catching with an ellipsis argument without rethrowing, and even if it did permit it, the result would be an unreported error). Neither POSIX nor the C++98/03 standard specifies what is to happen in that case. In practice, most implementations will call std::terminate() and so terminate the entire program, and this behaviour is required where the program is compiled under C++11. Accordingly, a user must make sure that no exceptions, other than Thread::Exit or any cancellation pseudo-exception, can propagate from the initial function executed by the new thread. This includes ensuring that, for any argument passed to that function which is not a built-in type and which is not taken by the function by const or non-const reference, the argument type's copy constructor does not throw.

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