2001-10-06 18:13:28 +04:00
|
|
|
#ifndef CTHREAD_H
|
|
|
|
#define CTHREAD_H
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
class IJob;
|
|
|
|
class CThreadRep;
|
|
|
|
|
|
|
|
// note -- do not derive from this class
|
|
|
|
class CThread {
|
2002-04-29 18:40:01 +04:00
|
|
|
public:
|
|
|
|
// create and start a new thread executing the job.
|
2001-10-06 18:13:28 +04:00
|
|
|
// the user data can be retrieved with getUserData().
|
2002-04-29 18:40:01 +04:00
|
|
|
CThread(IJob* adopted, void* userData = 0);
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// make a new thread object that refers to an existing thread.
|
2001-10-06 18:13:28 +04:00
|
|
|
// this does *not* start a new thread.
|
2002-04-29 18:40:01 +04:00
|
|
|
CThread(const CThread&);
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// release thread. this does not terminate the thread. a thread
|
|
|
|
// will keep running until the job completes or calls exit().
|
|
|
|
~CThread();
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// manipulators
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// assign thread. this has no effect on the threads. it simply
|
|
|
|
// makes this thread object refer to another thread. it does *not*
|
2001-10-06 18:13:28 +04:00
|
|
|
// start a new thread.
|
2002-04-29 18:40:01 +04:00
|
|
|
CThread& operator=(const CThread&);
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2001-10-14 22:29:43 +04:00
|
|
|
// initialize the thread library. this must be called before
|
|
|
|
// any other thread methods or creating a thread object. it
|
|
|
|
// is harmless to call init() multiple times.
|
|
|
|
static void init();
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// the calling thread sleeps for the given number of seconds. if
|
|
|
|
// timeout <= 0.0 then the call returns immediately. if timeout
|
2001-10-06 18:13:28 +04:00
|
|
|
// == 0.0 then the calling thread yields the CPU.
|
|
|
|
// (cancellation point)
|
2002-04-29 18:40:01 +04:00
|
|
|
static void sleep(double timeout);
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// terminate the calling thread. this function does not return but
|
|
|
|
// the stack is unwound and automatic objects are destroyed, as if
|
|
|
|
// exit() threw an exception (which is, in fact, what it does). the
|
|
|
|
// argument is saved as the result returned by getResult(). if you
|
|
|
|
// have a catch(...) block then you should add the following before
|
|
|
|
// it to avoid catching the exit: catch(CThreadExit&) { throw; }
|
|
|
|
static void exit(void*);
|
2001-10-06 18:13:28 +04:00
|
|
|
|
|
|
|
// enable/disable cancellation. default is enabled. this is not
|
|
|
|
// a cancellation point so if you enabled cancellation and want to
|
|
|
|
// allow immediate cancellation you need to call testCancel().
|
|
|
|
// return value is the previous state.
|
|
|
|
static bool enableCancel(bool);
|
|
|
|
|
|
|
|
// cancel the thread. cancel() never waits for the thread to
|
|
|
|
// terminate; it just posts the cancel and returns. a thread will
|
|
|
|
// terminate when it enters a cancellation point with cancellation
|
|
|
|
// enabled. if cancellation is disabled then the cancel is
|
|
|
|
// remembered but not acted on until the first call to a
|
|
|
|
// cancellation point after cancellation is enabled.
|
|
|
|
//
|
|
|
|
// a cancellation point is a function that can act on cancellation.
|
|
|
|
// a cancellation point does not return if there's a cancel pending.
|
|
|
|
// instead, it unwinds the stack and destroys automatic objects, as
|
|
|
|
// if cancel() threw an exception (which is, in fact, what it does).
|
|
|
|
// threads must take care to clean up and release any resources they
|
|
|
|
// may have, especially mutexes. they can catch (XThreadCancel) to
|
|
|
|
// do that then rethrow the exception or they can let it happen
|
|
|
|
// automatically by doing clean up in the d'tors of automatic
|
|
|
|
// objects. clients are strongly encouraged to do the latter.
|
|
|
|
// during cancellation, further cancel() calls are ignored (i.e.
|
|
|
|
// a thread cannot be interrupted by a cancel during cancellation).
|
|
|
|
//
|
|
|
|
// clients that catch (XThreadCancel) must always rethrow the
|
|
|
|
// exception. clients that catch(...) must either rethrow the
|
|
|
|
// exception or include a catch (XThreadCancel) handler that
|
|
|
|
// rethrows.
|
2002-04-29 18:40:01 +04:00
|
|
|
void cancel();
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// change the priority of the thread. normal priority is 0, 1 is
|
2001-10-06 18:13:28 +04:00
|
|
|
// the next lower, etc. -1 is the next higher, etc. but boosting
|
|
|
|
// the priority may not be available.
|
2002-04-29 18:40:01 +04:00
|
|
|
void setPriority(int n);
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// accessors
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// return a thread object representing the calling thread
|
|
|
|
static CThread getCurrentThread();
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// get the user data passed to the constructor for the current
|
2001-10-06 18:13:28 +04:00
|
|
|
// thread.
|
2002-04-29 18:40:01 +04:00
|
|
|
static void* getUserData();
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// testCancel() does nothing but is a cancellation point. call
|
2001-10-06 18:13:28 +04:00
|
|
|
// this to make a function itself a cancellation point.
|
|
|
|
// (cancellation point)
|
2002-04-29 18:40:01 +04:00
|
|
|
static void testCancel();
|
2001-10-06 18:13:28 +04:00
|
|
|
|
|
|
|
// waits for the thread to terminate (by exit() or cancel() or
|
|
|
|
// by returning from the thread job). returns immediately if
|
|
|
|
// the thread has already terminated. returns immediately with
|
|
|
|
// false if called by a thread on itself. returns false on
|
|
|
|
// timeout (or error) and true on success.
|
|
|
|
// (cancellation point)
|
|
|
|
bool wait(double timeout = -1.0) const;
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// get the exit result. does an implicit wait(). returns NULL
|
2001-10-06 18:13:28 +04:00
|
|
|
// immediately if called by a thread on itself. returns NULL for
|
|
|
|
// threads that were cancelled.
|
|
|
|
// (cancellation point)
|
|
|
|
void* getResult() const;
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// compare threads for (in)equality
|
|
|
|
bool operator==(const CThread&) const;
|
|
|
|
bool operator!=(const CThread&) const;
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
|
|
|
CThread(CThreadRep*);
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
|
|
|
CThreadRep* m_rep;
|
2001-10-06 18:13:28 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
// disables cancellation in the c'tor and enables it in the d'tor.
|
|
|
|
class CThreadMaskCancel {
|
2002-04-29 18:40:01 +04:00
|
|
|
public:
|
2001-10-06 18:13:28 +04:00
|
|
|
CThreadMaskCancel() : m_old(CThread::enableCancel(false)) { }
|
|
|
|
~CThreadMaskCancel() { CThread::enableCancel(m_old); }
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
2001-10-06 18:13:28 +04:00
|
|
|
bool m_old;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|