00001 #pragma once
00002 #ifndef AXPIPE_CTHREAD_H
00003 #define AXPIPE_CTHREAD_H
00004
00038 #include "AxPipe.h"
00039 #include "AxPipeAssert.h"
00040
00041 namespace AxPipe {
00042 using Assert::OutputDebugStringF;
00043
00053 class CNoThread {
00054 protected:
00055 bool m_fExit;
00056 bool m_fAutoDeleteSink;
00057
00059 virtual void WorkStart() {
00060 }
00062 virtual void WorkSignal() {
00063 Work();
00064 }
00066 virtual void WorkEnd() {
00067 }
00069 virtual void WorkWait() {
00070 }
00072 virtual void WorkExitWait() {
00073 }
00075 virtual void Work() = 0;
00076 public:
00077 CNoThread() {
00078 m_fAutoDeleteSink = m_fExit = false;
00079 }
00085 void WaitForIdle() {
00086 WorkStart();
00087 WorkEnd();
00088 }
00106 static void *ClassId() {
00107 static int i;
00108 return &i;
00109 }
00110
00113 virtual void *RTClassId() {
00114 return ClassId();
00115 }
00116 };
00117
00120
00121
00122 #pragma warning (push)
00123
00124 #pragma warning (disable: 4355)
00135 template <class T> class CThreadNoRun : public CThreadMain<T> {
00136 CThreadSync m_ThreadSync;
00137
00138 public:
00139
00141 virtual ~CThreadNoRun() {
00142 if (!m_fExit) {
00143 SetError(ERROR_CODE_INTERNAL, ERROR_MSG_INTERNAL, _T("CThread::~CThread Exit() not called"));
00144 }
00145 }
00146
00147 public:
00149 void WorkStart() {
00150 m_ThreadSync.WorkStart();
00151 }
00152
00154 void WorkSignal() {
00155 m_ThreadSync.WorkSignal();
00156 }
00157
00159 void WorkWait() {
00160 m_ThreadSync.WorkWait();
00161 }
00162
00164 void WorkEnd() {
00165 m_ThreadSync.WorkEnd();
00166 }
00167
00169 virtual void WorkExitWait() {
00170 Wait();
00171 }
00172 };
00173
00179 template <class T> class CThread : public CThreadNoRun<T> {
00180 public:
00181 CThread() {
00182 Run();
00183 }
00184 private:
00187 virtual int Main() {
00188 OutputDebugStringF(_T("CThread()::Main() ID=%X\n"), GetCurrentThreadId());
00189 while (!m_fExit) {
00190
00191 WorkWait();
00192 Work();
00193 WorkEnd();
00194 }
00195 OutputDebugStringF(_T("CThread()::Main() ID=%X WaitForIdle()...\n"), GetCurrentThreadId());
00196 WaitForIdle();
00197
00198
00199
00200 if (AxPipe::dwTlsIndex != TLS_OUT_OF_INDEXES) {
00201
00202 if (TlsGetValue(AxPipe::dwTlsIndex) != NULL) {
00203
00204 LocalFree(GetCurrentFiber());
00205 }
00206 }
00207 OutputDebugStringF(_T("CThread()::Main() ...exiting thread ID=%X\n"), GetCurrentThreadId());
00208 return 0;
00209 }
00210
00211 };
00212
00218 template <class T> class CThreadSource : public CThreadMain<T> {
00219 private:
00223 virtual int Main() {
00224 Open()->Drain()->Close()->Plug();
00225 return 0;
00226 }
00227 };
00228
00229 #pragma warning (pop)
00230
00231 };
00232 #endif AXPIPE_CTHREAD_H