From: <qr...@us...> - 2006-11-29 14:12:23
|
Revision: 221 http://svn.sourceforge.net/opengate/?rev=221&view=rev Author: qrstuvw Date: 2006-11-29 06:12:21 -0800 (Wed, 29 Nov 2006) Log Message: ----------- - Threading for Win32 and Posix - TODO: Implement this stuff into the META-server source (50% done) Added Paths: ----------- src/common/Mutex.h src/common/Posix/ src/common/Posix/Mutex.h src/common/Posix/Semaphore.h src/common/Posix/Thread.h src/common/Semaphore.h src/common/Thread.h src/common/Win32/ src/common/Win32/Mutex.h src/common/Win32/Semaphore.h src/common/Win32/Thread.h src/common/Win32/Win32.h Added: src/common/Mutex.h =================================================================== --- src/common/Mutex.h (rev 0) +++ src/common/Mutex.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,12 @@ +#ifndef _Mutex_ +#define _Mutex_ + +#include <errno.h> + +#ifdef WIN32 + #include "Win32/Mutex.h" +#else + #include "Posix/Mutex.h" +#endif + +#endif // !_Mutex_ Property changes on: src/common/Mutex.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: src/common/Posix/Mutex.h =================================================================== --- src/common/Posix/Mutex.h (rev 0) +++ src/common/Posix/Mutex.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////// +// Written by Phillip Sitbon +// Copyright 2003 +// +// Posix/Mutex.h +// - Resource locking mechanism using Posix mutexes +// +///////////////////////////////////////////////////////////////////// + +#ifndef _Mutex_Posix_ +#define _Mutex_Posix_ + +#include <pthread.h> + +class Mutex +{ + mutable pthread_mutex_t M; + void operator=(Mutex &M) {} + Mutex( const Mutex &M ) {} + + public: + + Mutex() + { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&M,&attr); + pthread_mutexattr_destroy(&attr); + } + + virtual ~Mutex() + { pthread_mutex_unlock(&M); pthread_mutex_destroy(&M); } + + int Lock() const + { return pthread_mutex_lock(&M); } + + int Lock_Try() const + { return pthread_mutex_trylock(&M); } + + int Unlock() const + { return pthread_mutex_unlock(&M); } +}; + +#endif // !_Mutex_Posix_ Property changes on: src/common/Posix/Mutex.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: src/common/Posix/Semaphore.h =================================================================== --- src/common/Posix/Semaphore.h (rev 0) +++ src/common/Posix/Semaphore.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,42 @@ +///////////////////////////////////////////////////////////////////// +// Written by Phillip Sitbon +// Copyright 2003 +// +// Posix/Semaphore.h +// - Resource counting mechanism +// +///////////////////////////////////////////////////////////////////// + +#ifndef _Semaphore_Posix_ +#define _Semaphore_Posix_ + +#include <semaphore.h> + +class Semaphore +{ + sem_t S; + + public: + Semaphore( int init = 0 ) + { sem_init(&S,0,init); } + + virtual ~Semaphore() + { sem_destroy(&S); } + + void Wait() const + { sem_wait((sem_t *)&S); } + + int Wait_Try() const + { return (sem_trywait((sem_t *)&S)?errno:0); } + + int Post() const + { return (sem_post((sem_t *)&S)?errno:0); } + + int Value() const + { int V = -1; sem_getvalue((sem_t *)&S,&V); return V; } + + void Reset( int init = 0 ) + { sem_destroy(&S); sem_init(&S,0,init); } +}; + +#endif // !_Semaphore_Posix_ Property changes on: src/common/Posix/Semaphore.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: src/common/Posix/Thread.h =================================================================== --- src/common/Posix/Thread.h (rev 0) +++ src/common/Posix/Thread.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,312 @@ +///////////////////////////////////////////////////////////////////// +// Written by Phillip Sitbon +// Copyright 2003 +// +// Posix/Thread.h +// - Posix thread +// +///////////////////////////////////////////////////////////////////// + +#ifndef _Thread_Posix_ +#define _Thread_Posix_ + +#include "Semaphore.h" +#include "Mutex.h" + +#include <pthread.h> + +#define InvalidHandle 0 + +template +< + typename Thread_T +> +class Thread +{ + private: + typedef struct Instance; + + public: + typedef Thread_T & Thread_R; + typedef const Thread_T & Thread_C_R; + + typedef pthread_t Handle; + typedef void ( *Handler)( Thread_R ); + + + protected: + Thread() {} + + virtual void ThreadMain( Thread_R ) = 0; + + static void Exit() + { pthread_exit(0); } + + static void TestCancel() + { pthread_testcancel(); } + + static Handle Self() + { return (Handle)pthread_self(); } + + public: + + static int Create( + const Handler & Function, + Thread_C_R Param, + Handle * const & H = 0, + const bool & CreateDetached = false, + const unsigned int & StackSize = 0, + const bool & CancelEnable = false, + const bool & CancelAsync = false + ) + { + M_Create().Lock(); + pthread_attr_t attr; + pthread_attr_init(&attr); + + if ( CreateDetached ) + pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); + + if ( StackSize ) + pthread_attr_setstacksize(&attr,StackSize); + + Instance I(Param,0,Function,CancelEnable,CancelAsync); + + int R = pthread_create((pthread_t *)H,&attr,ThreadMainHandler,(void *)&I); + pthread_attr_destroy(&attr); + + if ( !R ) S_Create().Wait(); + else if ( H ) *H = InvalidHandle; + + M_Create().Unlock(); + return errno; + } + + int Create( + Thread_C_R Param, + Handle * const & H = 0, + const bool & CreateDetached = false, + const unsigned int & StackSize = 0, + const bool & CancelEnable = false, + const bool & CancelAsync = false + ) const + { + M_Create().Lock(); + pthread_attr_t attr; + pthread_attr_init(&attr); + + if ( CreateDetached ) + pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); + + if ( StackSize ) + pthread_attr_setstacksize(&attr,StackSize); + + Instance I(Param,const_cast<Thread *>(this),0,CancelEnable,CancelAsync); + + int R = pthread_create((pthread_t *)H,&attr,ThreadMainHandler,(void *)&I); + pthread_attr_destroy(&attr); + + if ( !R ) S_Create().Wait(); + else if ( H ) *H = InvalidHandle; + + M_Create().Unlock(); + return errno; + } + + static int Join( Handle H ) + { return pthread_join(H,0); } + + static int Kill( Handle H ) + { return pthread_cancel(H); } + + static int Detach( Handle H ) + { return pthread_detach(H); } + + private: + + static const Mutex &M_Create() { static Mutex M; return M; } + static const Semaphore &S_Create() { static Semaphore S; return S; } + + static void *ThreadMainHandler( Instance *Param ) + { + Instance I(*Param); + Thread_T Data(I.Data); + S_Create().Post(); + + if ( I.Flags & 1 /*CancelEnable*/ ) + { + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); + + if ( I.Flags & 2 /*CancelAsync*/ ) + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); + else + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL); + } + else + { + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); + } + + if ( I.Owner ) + I.Owner->ThreadMain(Data); + else + I.pFN(Data); + + return 0; + } + + struct Instance + { + Instance( Thread_C_R P, Thread<Thread_T> *const &O, const Thread<Thread_T>::Handler &pH = 0, const bool &CE=false, const bool &CA=false ) + : pFN(pH), Data(P), Owner(O), Flags(0) { if ( CE ) Flags|=1; if ( CA ) Flags|=2; } + + Thread<Thread_T>::Thread_C_R Data; + Thread<Thread_T> * Owner; + Thread<Thread_T>::Handler pFN; + unsigned char Flags; + }; +}; + +///////////////////////////////////////////////////////////////////// +// Explicit specialization, no thread parameters +// + +class Thread<void> +{ + private: + typedef struct Instance; + + public: + typedef pthread_t Handle; + typedef void ( *Handler)(); + + protected: + Thread<void>() {} + + virtual void ThreadMain() = 0; + + static void Exit() + { pthread_exit(0); } + + static void TestCancel() + { pthread_testcancel(); } + + static Handle Self() + { return (Handle)pthread_self(); } + + public: + + static int Create( + const Handler & Function, + Handle * const & H = 0, + const bool & CreateDetached = false, + const unsigned int & StackSize = 0, + const bool & CancelEnable = false, + const bool & CancelAsync = false + ) + { + M_Create().Lock(); + pthread_attr_t attr; + pthread_attr_init(&attr); + + if ( CreateDetached ) + pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); + + if ( StackSize ) + pthread_attr_setstacksize(&attr,StackSize); + + Instance I(0,Function,CancelEnable,CancelAsync); + + int R = pthread_create((pthread_t *)H,&attr,ThreadMainHandler,(void *)&I); + pthread_attr_destroy(&attr); + + if ( !R ) S_Create().Wait(); + else if ( H ) *H = InvalidHandle; + + M_Create().Unlock(); + return errno; + } + + int Create( + Handle * const & H = 0, + const bool & CreateDetached = false, + const unsigned int & StackSize = 0, + const bool & CancelEnable = false, + const bool & CancelAsync = false + ) const + { + M_Create().Lock(); + pthread_attr_t attr; + pthread_attr_init(&attr); + + if ( CreateDetached ) + pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); + + if ( StackSize ) + pthread_attr_setstacksize(&attr,StackSize); + + Instance I(const_cast<Thread *>(this),0,CancelEnable,CancelAsync); + + int R = pthread_create((pthread_t *)H,&attr,ThreadMainHandler,(void *)&I); + pthread_attr_destroy(&attr); + + if ( !R ) S_Create().Wait(); + else if ( H ) *H = InvalidHandle; + + M_Create().Unlock(); + return errno; + } + + static int Join( Handle H ) + { return pthread_join(H,0); } + + static int Kill( Handle H ) + { return pthread_cancel(H); } + + static int Detach( Handle H ) + { return pthread_detach(H); } + + private: + + static const Mutex &M_Create() { static Mutex M; return M; } + static const Semaphore &S_Create() { static Semaphore S; return S; } + + static void *ThreadMainHandler( Instance *Param ) + { + Instance I(*Param); + S_Create().Post(); + + if ( I.Flags & 1 /*CancelEnable*/ ) + { + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); + + if ( I.Flags & 2 /*CancelAsync*/ ) + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); + else + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL); + } + else + { + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL); + } + + if ( I.Owner ) + I.Owner->ThreadMain(); + else + I.pFN(); + + return 0; + } + + struct Instance + { + Instance( Thread<void> *const &O, const Thread<void>::Handler &pH = 0, const bool &CE=false, const bool &CA=false ) + : pFN(pH), Owner(O), Flags(0) { if ( CE ) Flags|=1; if ( CA ) Flags|=2; } + + Thread<void> * Owner; + Thread<void>::Handler pFN; + unsigned char Flags; + }; +}; + +#endif // !_Thread_Posix_ Property changes on: src/common/Posix/Thread.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: src/common/Semaphore.h =================================================================== --- src/common/Semaphore.h (rev 0) +++ src/common/Semaphore.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,12 @@ +#ifndef _Semaphore_ +#define _Semaphore_ + +#include <errno.h> + +#ifdef WIN32 + #include "Win32/Semaphore.h" +#else + #include "Posix/Semaphore.h" +#endif + +#endif // !_Semaphore_ Property changes on: src/common/Semaphore.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: src/common/Thread.h =================================================================== --- src/common/Thread.h (rev 0) +++ src/common/Thread.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,12 @@ +#ifndef _Thread_ +#define _Thread_ + +#include <errno.h> + +#ifdef WIN32 + #include "Win32/Thread.h" +#else + #include "Posix/Thread.h" +#endif + +#endif // !_Thread_ Property changes on: src/common/Thread.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: src/common/Win32/Mutex.h =================================================================== --- src/common/Win32/Mutex.h (rev 0) +++ src/common/Win32/Mutex.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////// +// Written by Phillip Sitbon +// Copyright 2003 +// +// Win32/Mutex.h +// - Resource locking mechanism using Critical Sections +// +///////////////////////////////////////////////////////////////////// + +#ifndef _Mutex_Win32_ +#define _Mutex_Win32_ + +#include "Win32.h" + +class Mutex +{ + mutable CRITICAL_SECTION C; + void operator=(Mutex &M) {} + Mutex( const Mutex &M ) {} + + public: + + Mutex() + { InitializeCriticalSection(&C); } + + virtual ~Mutex() + { DeleteCriticalSection(&C); } + + int Lock() const + { EnterCriticalSection(&C); return 0; } + +#if(_WIN32_WINNT >= 0x0400) + int Lock_Try() const + { return (TryEnterCriticalSection(&C)?0:EBUSY); } +#endif + + int Unlock() const + { LeaveCriticalSection(&C); return 0; } +}; + +#endif // !_Mutex_Win32_ Property changes on: src/common/Win32/Mutex.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: src/common/Win32/Semaphore.h =================================================================== --- src/common/Win32/Semaphore.h (rev 0) +++ src/common/Win32/Semaphore.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////// +// Written by Phillip Sitbon +// Copyright 2003 +// +// Win32/Semaphore.h +// - Resource counting mechanism +// +///////////////////////////////////////////////////////////////////// +#ifndef _Semaphore_Win32_ +#define _Semaphore_Win32_ + +#include "Win32.h" + +#define SEM_VALUE_MAX ((int) ((~0u) >> 1)) + +class Semaphore +{ + HANDLE S; + void operator=(const Semaphore &S){} + Semaphore(const Semaphore &S){} + + public: + Semaphore( int init = 0 ) + { S = CreateSemaphore(0,init,SEM_VALUE_MAX,0); } + + virtual ~Semaphore() + { CloseHandle(S); } + + void Wait() const + { WaitForSingleObject((HANDLE)S,INFINITE); } + + int Wait_Try() const + { return ((WaitForSingleObject((HANDLE)S,INFINITE)==WAIT_OBJECT_0)?0:EAGAIN); } + + int Post() const + { return (ReleaseSemaphore((HANDLE)S,1,0)?0:ERANGE); } + + int Value() const + { LONG V = -1; ReleaseSemaphore((HANDLE)S,0,&V); return V; } + + void Reset( int init = 0 ) + { + CloseHandle(S); + S = CreateSemaphore(0,init,SEM_VALUE_MAX,0); + } +}; + +#endif // !_Semaphore_Win32_ Property changes on: src/common/Win32/Semaphore.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: src/common/Win32/Thread.h =================================================================== --- src/common/Win32/Thread.h (rev 0) +++ src/common/Win32/Thread.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,339 @@ +///////////////////////////////////////////////////////////////////// +// Written by Phillip Sitbon +// Copyright 2003 +// +// Win32/Thread.h +// - Windows thread +// +// - From CreateThread Platform SDK Documentation: +// +// "A thread that uses functions from the static C run-time +// libraries should use the beginthread and endthread C run-time +// functions for thread management rather than CreateThread and +// ExitThread. Failure to do so results in small memory leaks +// when ExitThread is called. Note that this is not a problem +// with the C run-time in a DLL." +// +// With regards to this, I have decided to use the CreateThread +// API, unless you define _CRT_ in which case there are two +// possibilities: +// +// 1. Define _USE_BEGINTHREAD: Uses _beginthread/_endthread +// (said to be *unreliable* in the SDK docs) +// +// 2. Don't - Uses _beginthreaded/_endthreadex +// +// A note about _endthread: +// +// It will call CloseHandle() on exit, and if it was already +// closed then you will get an exception. To prevent this, I +// removed the CloseHandle() functionality - this means that +// a Join() WILL wait on a Detach()'ed thread. +// +///////////////////////////////////////////////////////////////////// +#ifndef _Thread_Win32_ +#define _Thread_Win32_ + +#include "Win32.h" +#include "Semaphore.h" +#include "Mutex.h" + +#ifdef _CRT_ +# include <process.h> +# ifdef _USE_BEGINTHREAD +# define THREAD_CALL __cdecl +# define THREAD_HANDLE uintptr_t +# define THREAD_RET_T void +# define CREATE_THREAD_FAILED (-1L) +# define CREATE_THREAD_ERROR (errno) +# define CREATE_THREAD(_S,_F,_P) ((Handle)_beginthread((void (__cdecl *)(void *))_F,_S,(void *)_P)) +# define EXIT_THREAD _endthread() +# define CLOSE_HANDLE(x) 1 +# define THREAD_RETURN(x) return +# else +# define THREAD_CALL WINAPI +# define THREAD_HANDLE HANDLE +# define THREAD_RET_T UINT +# define CREATE_THREAD_FAILED (0L) +# define CREATE_THREAD_ERROR (errno) +# define CREATE_THREAD(_S,_F,_P) ((Handle)_beginthreadex(0,_S,(UINT (WINAPI *)(void *))_F,(void *)_P,0,0)) +# define EXIT_THREAD _endthreadex(0) +# define CLOSE_HANDLE(x) CloseHandle(x) +# define THREAD_RETURN(x) return(x) +# endif +#else +# define THREAD_CALL WINAPI +# define THREAD_HANDLE HANDLE +# define THREAD_RET_T DWORD +# define CREATE_THREAD_FAILED (0L) +# define CREATE_THREAD_ERROR GetLastError() +# define CREATE_THREAD(_S,_F,_P) ((Handle)CreateThread(0,_S,(DWORD (WINAPI *)(void *))_F,(void *)_P,0,0)) +# define EXIT_THREAD ExitThread(0) +# define CLOSE_HANDLE(x) CloseHandle(x) +# define THREAD_RETURN(x) return(x) +#endif + +#define InvalidHandle 0 + +template +< + typename Thread_T +> +class Thread +{ + private: + typedef struct Instance; + + public: + typedef Thread_T & Thread_R; + typedef const Thread_T & Thread_C_R; + + typedef THREAD_HANDLE Handle; + typedef void (* Handler)( Thread_R ); + + protected: + Thread() {} + + virtual void ThreadMain( Thread_R ) = 0; + + static void Exit() + { EXIT_THREAD; } + + static void TestCancel() + { Sleep(0); } + + static Handle Self() + { + //Handle Hnd = InvalidHandle; + //DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),(LPHANDLE)&Hnd,NULL,0,NULL); + //return Hnd; + + // only a pseudo-handle! + return (Handle)GetCurrentThread(); + } + + public: + + static int Create( + const Handler & Function, + Thread_C_R Param, + Handle * const & H = 0, + const bool & CreateDetached = false, + const unsigned int & StackSize = 0, + const bool & CancelEnable = false, // UNUSED + const bool & CancelAsync = false // UNUSED + ) + { + M_Create().Lock(); + + Instance I(Param,0,Function); + + Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler,&I)); + + if ( Hnd == CREATE_THREAD_FAILED ) + { + if ( H ) *H = InvalidHandle; + M_Create().Unlock(); + return CREATE_THREAD_ERROR; + } + + if ( H ) *H = Hnd; + + S_Create().Wait(); + M_Create().Unlock(); + + if ( CreateDetached ) CLOSE_HANDLE(Hnd); + return 0; + } + + int Create( + Thread_C_R Param, + Handle * const & H = 0, + const bool & CreateDetached = false, + const unsigned int & StackSize = 0, + const bool & CancelEnable = false, // UNUSED + const bool & CancelAsync = false // UNUSED + ) const + { + M_Create().Lock(); + + Instance I(Param,const_cast<Thread *>(this)); + + Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler,&I)); + + if ( Hnd == CREATE_THREAD_FAILED ) + { + if ( H ) *H = InvalidHandle; + M_Create().Unlock(); + return CREATE_THREAD_ERROR; + } + + if ( H ) *H = Hnd; + + S_Create().Wait(); + M_Create().Unlock(); + + if ( CreateDetached ) CLOSE_HANDLE(Hnd); + return 0; + } + + static int Join( const Handle &H ) + { + DWORD R = WaitForSingleObject((HANDLE)H,INFINITE); + + if ( (R == WAIT_OBJECT_0) || (R == WAIT_ABANDONED) ) + { + CLOSE_HANDLE(H); + return 0; + } + + if ( R == WAIT_TIMEOUT ) return EAGAIN; + return EINVAL; + } + + static int Kill( const Handle &H ) + { return TerminateThread((HANDLE)H,0) ? 0 : EINVAL; } + + static int Detach( const Handle &H ) + { return (CLOSE_HANDLE(H)?0:EINVAL); } + + private: + + static const Mutex &M_Create() { static Mutex M; return M; } + static const Semaphore &S_Create() { static Semaphore S; return S; } + + static THREAD_RET_T THREAD_CALL ThreadMainHandler( Instance *Param ) + { + Instance I(*Param); + Thread_T Data(I.Data); + S_Create().Post(); + + if ( I.Owner ) + I.Owner->ThreadMain(Data); + else + I.pFN(Data); + + Exit(); + THREAD_RETURN(0); + } + + struct Instance + { + Instance( Thread_C_R P, Thread<Thread_T> *const &O, const Thread<Thread_T>::Handler &pH = 0 ) + : pFN(pH), Data(P), Owner(O) {} + + Thread<Thread_T>::Thread_C_R Data; + Thread<Thread_T> * Owner; + Thread<Thread_T>::Handler pFN; + }; +}; + +///////////////////////////////////////////////////////////////////// +// Explicit Specialization of void +// +class Thread<void> +{ + private: + typedef struct Instance; + + public: + typedef THREAD_HANDLE Handle; + typedef void ( *Handler)(); + + protected: + Thread<void>() {} + + virtual void ThreadMain() = 0; + + static void Exit() + { EXIT_THREAD; } + + static void TestCancel() + { Sleep(0); } + + static Handle Self() + { return (Handle)GetCurrentThread(); } + + public: + + static int Create( + const Handler & Function, + Handle * const & H = 0, + const bool & CreateDetached = false, + const unsigned int & StackSize = 0, + const bool & CancelEnable = false, // UNUSED + const bool & CancelAsync = false // UNUSED + ) + { + Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler_S,Function)); + + if ( Hnd == CREATE_THREAD_FAILED ) + { + if ( H ) *H = InvalidHandle; + return CREATE_THREAD_ERROR; + } + + if ( H ) *H = Hnd; + if ( CreateDetached ) CLOSE_HANDLE(Hnd); + return 0; + } + + int Create( + Handle * const & H = 0, + const bool & CreateDetached = false, + const unsigned int & StackSize = 0, + const bool & CancelEnable = false, // UNUSED + const bool & CancelAsync = false // UNUSED + ) const + { + Handle Hnd(CREATE_THREAD(StackSize,ThreadMainHandler,this)); + + if ( Hnd == CREATE_THREAD_FAILED ) + { + if ( H ) *H = InvalidHandle; + return CREATE_THREAD_ERROR; + } + + if ( H ) *H = Hnd; + if ( CreateDetached ) CLOSE_HANDLE(Hnd); + return 0; + } + + static int Join( const Handle &H ) + { + DWORD R = WaitForSingleObject((HANDLE)H,INFINITE); + + if ( (R == WAIT_OBJECT_0) || (R == WAIT_ABANDONED) ) + { + CLOSE_HANDLE(H); + return 0; + } + + if ( R == WAIT_TIMEOUT ) return EAGAIN; + return EINVAL; + } + + static int Kill( const Handle &H ) + { return TerminateThread((HANDLE)H,0) ? 0 : EINVAL; } + + static int Detach( const Handle &H ) + { return (CLOSE_HANDLE(H)?0:EINVAL); } + + private: + + static THREAD_RET_T THREAD_CALL ThreadMainHandler( Thread<void> *Param ) + { + Param->ThreadMain(); + Exit(); + THREAD_RETURN(0); + } + + static THREAD_RET_T THREAD_CALL ThreadMainHandler_S( Handler Param ) + { + Param(); + Exit(); + THREAD_RETURN(0); + } +}; + +#endif // !_Thread_Win32_ Property changes on: src/common/Win32/Thread.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native Added: src/common/Win32/Win32.h =================================================================== --- src/common/Win32/Win32.h (rev 0) +++ src/common/Win32/Win32.h 2006-11-29 14:12:21 UTC (rev 221) @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////// +// Written by Phillip Sitbon +// Copyright 2003 +// +// Win32.h +// - Windows includes +// +///////////////////////////////////////////////////////////////////// +#ifndef _Win32_ +#define _Win32_ + + #if !defined(_WINDOWS_) + // WIN32 Excludes + #ifdef WIN32_LEAN_AND_MEAN + # define VC_EXTRALEAN + # define WIN32_LEAN_AND_MEAN + # define _PRSHT_H_ + # define NOGDICAPMASKS // CC_*, LC_*, PC_*, CP_*, TC_*, RC_ + # define NOVIRTUALKEYCODES // VK_* + # define NOWINMESSAGES // WM_*, EM_*, LB_*, CB_* + # define NOWINSTYLES // WS_*, CS_*, ES_*, LBS_*, SBS_*, CBS_* + # define NOSYSMETRICS // SM_* + # define NOMENUS // MF_* + # define NOICONS // IDI_* + # define NOKEYSTATES // MK_* + # define NOSYSCOMMANDS // SC_* + # define NORASTEROPS // Binary and Tertiary raster ops + # define NOSHOWWINDOW // SW_* + # define OEMRESOURCE // OEM Resource values + # define NOATOM // Atom Manager routines + # define NOCLIPBOARD // Clipboard routines + # define NOCOLOR // Screen colors + # define NOCTLMGR // Control and Dialog routines + # define NODRAWTEXT // DrawText() and DT_* + # define NOGDI // All GDI defines and routines + # define NOKERNEL // All KERNEL defines and routines + # define NOUSER // All USER defines and routines + # define NONLS // All NLS defines and routines + # define NOMB // MB_* and MessageBox() + # define NOMEMMGR // GMEM_*, LMEM_*, GHND, LHND, associated routines + # define NOMETAFILE // typedef METAFILEPICT + # define NOMINMAX // Macros min(a,b) and max(a,b) + # define NOMSG // typedef MSG and associated routines + # define NOOPENFILE // OpenFile(), OemToAnsi, AnsiToOem, and OF_* + # define NOSCROLL // SB_* and scrolling routines + # define NOSERVICE // All Service Controller routines, SERVICE_ equates, etc. + # define NOSOUND // Sound driver routines + # define NOTEXTMETRIC // typedef TEXTMETRIC and associated routines + # define NOWH // SetWindowsHook and WH_* + # define NOWINOFFSETS // GWL_*, GCL_*, associated routines + # define NOCOMM // COMM driver routines + # define NOKANJI // Kanji support stuff. + # define NOHELP // Help engine interface. + # define NOPROFILER // Profiler interface. + # define NODEFERWINDOWPOS // DeferWindowPos routines + # define NOMCX // Modem Configuration Extensions + #endif // WIN32_LEAN_AND_MEAN + // + # include <windows.h> + #endif + +#endif // !_Win32_ \ No newline at end of file Property changes on: src/common/Win32/Win32.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |