2001-10-06 18:13:28 +04:00
|
|
|
#ifndef CTHREADREP_H
|
|
|
|
#define CTHREADREP_H
|
|
|
|
|
2002-06-19 15:23:49 +04:00
|
|
|
#include "common.h"
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-06-19 15:23:49 +04:00
|
|
|
#if HAVE_PTHREAD
|
2001-10-06 18:13:28 +04:00
|
|
|
#include <pthread.h>
|
2002-06-19 15:23:49 +04:00
|
|
|
#elif WINDOWS_LIKE
|
2002-06-10 20:49:46 +04:00
|
|
|
#define WIN32_LEAN_AND_MEAN
|
2001-10-06 18:13:28 +04:00
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
2001-10-14 22:29:43 +04:00
|
|
|
class CMutex;
|
2001-10-06 18:13:28 +04:00
|
|
|
class IJob;
|
|
|
|
|
|
|
|
class CThreadRep {
|
2002-04-29 18:40:01 +04:00
|
|
|
public:
|
2001-10-06 18:13:28 +04:00
|
|
|
CThreadRep(IJob*, void* userData);
|
|
|
|
|
|
|
|
// manipulators
|
|
|
|
|
2001-10-14 22:29:43 +04:00
|
|
|
// initialize the thread library
|
|
|
|
static void initThreads();
|
|
|
|
|
2001-10-06 18:13:28 +04:00
|
|
|
// change ref count
|
|
|
|
void ref();
|
|
|
|
void unref();
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// the calling thread sleeps for t seconds. if t == 0.0 then
|
|
|
|
// the thread yields the CPU.
|
|
|
|
void sleep(double timeout);
|
2001-10-06 18:13:28 +04:00
|
|
|
|
|
|
|
// cancel the thread
|
|
|
|
void cancel();
|
|
|
|
|
|
|
|
// set cancellation state
|
|
|
|
bool enableCancel(bool enable);
|
|
|
|
|
|
|
|
// permanently disable further cancellation and start cancel cleanup
|
|
|
|
// if cancel has been called and cancellation hasn't been started yet.
|
|
|
|
void testCancel();
|
|
|
|
|
|
|
|
// wait for thread to exit or for current thread to cancel
|
|
|
|
bool wait(CThreadRep*, double timeout);
|
|
|
|
|
2002-06-19 15:23:49 +04:00
|
|
|
#if WINDOWS_LIKE
|
2002-06-14 22:08:20 +04:00
|
|
|
// wait for a message on the queue
|
|
|
|
bool waitForEvent(double timeout);
|
|
|
|
#endif
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// set the priority
|
|
|
|
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
|
|
|
// get the exit result for this thread. thread must be terminated.
|
|
|
|
void* getResult() const;
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// get the user data passed to the constructor
|
|
|
|
void* getUserData() const;
|
2001-10-06 18:13:28 +04:00
|
|
|
|
|
|
|
// get the current cancellable state
|
|
|
|
bool isCancellable() const;
|
|
|
|
|
2002-06-19 15:23:49 +04:00
|
|
|
#if HAVE_PTHREAD
|
2001-10-06 18:13:28 +04:00
|
|
|
bool isExited() const;
|
2002-06-19 15:23:49 +04:00
|
|
|
#elif WINDOWS_LIKE
|
2001-10-06 18:13:28 +04:00
|
|
|
HANDLE getExitEvent() const;
|
|
|
|
HANDLE getCancelEvent() const;
|
|
|
|
#endif
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
// return the thread rep for the calling thread. the returned
|
|
|
|
// rep has been ref()'d.
|
|
|
|
static CThreadRep* getCurrentThreadRep();
|
2001-10-06 18:13:28 +04:00
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
protected:
|
2001-10-06 18:13:28 +04:00
|
|
|
virtual ~CThreadRep();
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
2001-10-06 18:13:28 +04:00
|
|
|
// internal constructor
|
|
|
|
CThreadRep();
|
|
|
|
|
|
|
|
// initialization/cleanup
|
|
|
|
void init();
|
|
|
|
void fini();
|
|
|
|
|
|
|
|
// thread rep lookup
|
|
|
|
static CThreadRep* find();
|
|
|
|
|
|
|
|
// thread functions
|
2002-06-19 15:23:49 +04:00
|
|
|
#if HAVE_PTHREAD
|
2001-10-06 18:13:28 +04:00
|
|
|
static void* threadFunc(void* arg);
|
|
|
|
static void threadCancel(int);
|
2002-06-02 22:49:35 +04:00
|
|
|
static void* threadSignalHandler(void*);
|
2002-06-19 15:23:49 +04:00
|
|
|
#elif WINDOWS_LIKE
|
2001-10-06 18:13:28 +04:00
|
|
|
static unsigned int __stdcall threadFunc(void* arg);
|
|
|
|
#endif
|
|
|
|
void doThreadFunc();
|
|
|
|
|
|
|
|
// not implemented
|
|
|
|
CThreadRep(const CThreadRep&);
|
|
|
|
CThreadRep& operator=(const CThreadRep&);
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
2001-10-14 22:29:43 +04:00
|
|
|
static CMutex* s_mutex;
|
2001-10-06 18:13:28 +04:00
|
|
|
static CThreadRep* s_head;
|
|
|
|
|
|
|
|
CThreadRep* m_prev;
|
|
|
|
CThreadRep* m_next;
|
|
|
|
|
2002-06-19 15:23:49 +04:00
|
|
|
int m_refCount;
|
2001-10-06 18:13:28 +04:00
|
|
|
IJob* m_job;
|
|
|
|
void* m_userData;
|
|
|
|
void* m_result;
|
|
|
|
bool m_cancellable;
|
|
|
|
bool m_cancelling;
|
|
|
|
|
2002-06-19 15:23:49 +04:00
|
|
|
#if HAVE_PTHREAD
|
2001-10-06 18:13:28 +04:00
|
|
|
pthread_t m_thread;
|
|
|
|
bool m_exit;
|
|
|
|
bool m_cancel;
|
2002-06-02 22:49:35 +04:00
|
|
|
static pthread_t s_signalThread;
|
2001-10-06 18:13:28 +04:00
|
|
|
#endif
|
|
|
|
|
2002-06-19 15:23:49 +04:00
|
|
|
#if WINDOWS_LIKE
|
2001-10-06 18:13:28 +04:00
|
|
|
HANDLE m_thread;
|
|
|
|
DWORD m_id;
|
|
|
|
HANDLE m_exit;
|
|
|
|
HANDLE m_cancel;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2001-11-19 03:33:36 +03:00
|
|
|
//
|
|
|
|
// CThreadPtr -- auto unref'ing pointer to thread rep
|
|
|
|
//
|
|
|
|
|
|
|
|
class CThreadPtr {
|
2002-04-29 18:40:01 +04:00
|
|
|
public:
|
2001-11-19 03:33:36 +03:00
|
|
|
CThreadPtr(CThreadRep* rep) : m_rep(rep) { }
|
|
|
|
~CThreadPtr() { m_rep->unref(); }
|
|
|
|
|
|
|
|
CThreadRep* operator->() const { return m_rep; }
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
2001-11-19 03:33:36 +03:00
|
|
|
// not implemented
|
|
|
|
CThreadPtr(const CThreadPtr&);
|
|
|
|
CThreadPtr& operator=(const CThreadPtr&);
|
|
|
|
|
2002-04-29 18:40:01 +04:00
|
|
|
private:
|
2001-11-19 03:33:36 +03:00
|
|
|
CThreadRep* m_rep;
|
|
|
|
};
|
|
|
|
|
2001-10-06 18:13:28 +04:00
|
|
|
#endif
|