Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #pragma once
00015
00019 #ifdef KNET_USE_BOOST
00020 #include <boost/thread.hpp>
00021 #elif WIN32
00022 #include <Windows.h>
00023
00024 #include "Event.h"
00025
00026 namespace kNet
00027 {
00028 typedef void (*ThreadEntryFunc)(void *threadStartData);
00029 }
00030
00031 #endif
00032
00033 #define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
00034
00035 #include "SharedPtr.h"
00036
00037 namespace kNet
00038 {
00039
00040 #ifdef KNET_USE_BOOST
00041 typedef boost::thread::id ThreadId;
00042 #else
00043 typedef unsigned int ThreadId;
00044 #endif
00045
00046 class Thread : public RefCountable
00047 {
00048 public:
00049 Thread();
00050 ~Thread();
00051
00054 bool ShouldQuit() const;
00055
00057 bool IsRunning() const;
00058
00060 void Hold();
00061
00063 void Resume();
00064
00067 void CheckHold();
00068
00071 void Stop();
00072
00073 template<typename Class, typename MemberFuncPtr, typename FuncParam>
00074 void Run(Class *obj, MemberFuncPtr memberFuncPtr, const FuncParam ¶m);
00075
00076 template<typename Class, typename MemberFuncPtr>
00077 void Run(Class *obj, MemberFuncPtr memberFuncPtr);
00078
00081 static void Sleep(int msecs);
00082
00083 ThreadId Id();
00084
00085 static ThreadId CurrentThreadId();
00086 private:
00087 Thread(const Thread &);
00088 void operator =(const Thread &);
00089
00090 class ObjInvokeBase : public RefCountable
00091 {
00092 public:
00093 virtual void Invoke() = 0;
00094 virtual ~ObjInvokeBase() {}
00095
00096 void operator()()
00097 {
00098 Invoke();
00099 }
00100 };
00101
00102 template<typename Class, typename MemberFuncPtr>
00103 class ObjInvokerVoid : public ObjInvokeBase
00104 {
00105 public:
00106 Class *obj;
00107 MemberFuncPtr memberFuncPtr;
00108 ObjInvokerVoid(Class *obj_, MemberFuncPtr memberFuncPtr_)
00109 :obj(obj_), memberFuncPtr(memberFuncPtr_){}
00110
00111 virtual void Invoke() { CALL_MEMBER_FN(*obj, memberFuncPtr)(); }
00112 };
00113
00114 template<typename Class, typename MemberFuncPtr, typename FuncParam>
00115 class ObjInvokerUnary : public ObjInvokeBase
00116 {
00117 public:
00118 Class *obj;
00119 MemberFuncPtr memberFuncPtr;
00120 FuncParam param;
00121 ObjInvokerUnary(Class *obj_, MemberFuncPtr memberFuncPtr_, const FuncParam ¶m_)
00122 :obj(obj_), memberFuncPtr(memberFuncPtr_),param(param_){}
00123
00124 virtual void Invoke() { CALL_MEMBER_FN(*obj, memberFuncPtr)(param); }
00125 };
00126
00127 ObjInvokeBase *invoker;
00128
00129
00130 Event threadHoldEvent;
00131 Event threadHoldEventAcked;
00132 Event threadResumeEvent;
00133
00134 void StartThread();
00135
00136 #ifdef KNET_USE_BOOST
00137 boost::thread thread;
00138 #elif WIN32
00139 HANDLE threadHandle;
00140
00142 void _ThreadRun();
00143
00144 friend DWORD WINAPI ThreadEntryPoint(LPVOID lpParameter);
00145 private:
00146 bool threadEnabled;
00147
00148 #endif
00149 };
00150
00151 template<typename Class, typename MemberFuncPtr, typename FuncParam>
00152 void Thread::Run(Class *obj, MemberFuncPtr memberFuncPtr, const FuncParam ¶m)
00153 {
00154 Stop();
00155 invoker = new ObjInvokerUnary<Class, MemberFuncPtr, FuncParam>(obj, memberFuncPtr, param);
00156 StartThread();
00157 }
00158
00159 template<typename Class, typename MemberFuncPtr>
00160 void Thread::Run(Class *obj, MemberFuncPtr memberFuncPtr)
00161 {
00162 Stop();
00163 invoker = new ObjInvokerVoid<Class, MemberFuncPtr>(obj, memberFuncPtr);
00164 StartThread();
00165 }
00166
00167 }