00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef THREAD_CLASS
00033 #define THREAD_CLASS
00034
00035 #ifndef WINDOWS
00036 #if defined(WIN32) || defined(WIN64)
00037 #define WINDOWS
00038 #endif
00039 #endif
00040
00041 #ifndef WINDOWS
00042 #include <stdio.h>
00043 #include <malloc.h>
00044 #include <memory.h>
00045 #include <pthread.h>
00046 #include <stdlib.h>
00047 #include <time.h>
00048 #include <errno.h>
00049 typedef bool BOOL;
00050 #define false false
00051 typedef long DWORD;
00052 typedef void *LPVOID;
00053 #else
00054 #include "afx.h"
00055 #include <windows.h>
00056 #include <stdio.h>
00057 #endif
00058
00059
00060 #if defined(AS400) || defined(OS400)
00061 typedef pthread_id_np_t ThreadId_t;
00062 #elif defined(VMS)
00063 typedef pthread_t ThreadId_t;
00064 #else
00065 typedef DWORD ThreadId_t;
00066 #endif
00067
00068 #include "MutexClass.h"
00069 #include "EventClass.h"
00070
00071 #define QUE_SIZE 100
00072 #define DEFAULT_STACK_SIZE 0
00073 #ifndef WINDOWS
00074 void Sleep( unsigned int mseconds);
00075 #endif
00076
00077 typedef enum {
00078 ThreadStateBusy,
00079 ThreadStateWaiting,
00080 ThreadStateDown,
00081 ThreadStateShuttingDown,
00082 ThreadStateFault
00083
00084 } ThreadState_t;
00085
00086 typedef enum {
00087 ThreadTypeEventDriven,
00088 ThreadTypeIntervalDriven } ThreadType_t;
00089
00090 typedef enum {
00091 TaskStatusNotSubmitted,
00092 TaskStatusWaitingOnQueue,
00093 TaskStatusBeingProcessed,
00094 TaskStatusCompleted } TaskStatus_t;
00095
00096 class CTask
00097 {
00098 private:
00099 TaskStatus_t m_state;
00100 ThreadId_t m_dwThread;
00101 public:
00102 CMutexClass m_mutex;
00103
00104 void SetTaskStatus(TaskStatus_t state)
00105 {
00106 m_mutex.Lock();
00107 m_state=state;
00108 m_mutex.Unlock();
00109 }
00110
00111 void SetId(ThreadId_t *pid)
00112 {
00113 memcpy(&m_dwThread,pid,sizeof(ThreadId_t));
00114 }
00115
00123 BOOL Wait(int timeoutSeconds)
00124 {
00125 timeoutSeconds = timeoutSeconds * 1000;
00126 if( Status() != TaskStatusCompleted &&
00127 timeoutSeconds > 0 )
00128 {
00129 Sleep(100);
00130 timeoutSeconds = timeoutSeconds - 100;
00131 }
00132 if( Status() == TaskStatusCompleted ) return true;
00133 return false;
00134 }
00135
00142 TaskStatus_t Status()
00143 {
00144 TaskStatus_t state ;
00145
00146 m_mutex.Lock();
00147 state = m_state;
00148 m_mutex.Unlock();
00149 return state;
00150 }
00151
00152 void Thread(ThreadId_t *pId)
00153 {
00154 memcpy(pId,&m_dwThread,sizeof(ThreadId_t));
00155 }
00156
00157 CTask(){m_state=TaskStatusNotSubmitted; memset(&m_dwThread,0,sizeof(ThreadId_t)); }
00158 ~CTask(){}
00159 virtual BOOL Task()=0;
00160 };
00161
00162
00163 class CThread
00164 #ifdef WINDOWS
00165 : public CObject
00166
00167 #endif
00168 {
00169 private:
00170 CEventClass m_event;
00171
00172 BOOL m_bRunning;
00173 #ifdef WINDOWS
00174 HANDLE m_thread;
00175 #else
00176 pthread_t m_thread;
00177 #endif
00178 ThreadId_t m_dwId;
00179 LPVOID *m_lppvQue;
00180 unsigned int m_chQue;
00181 unsigned int m_quePos;
00182 LPVOID m_lpvProcessor;
00183 ThreadState_t m_state;
00184
00185 DWORD m_dwIdle;
00186 ThreadType_t m_type;
00187 DWORD m_stackSize;
00188 #define NO_ERRORS 0
00189 #define MUTEX_CREATION 0x01
00190 #define EVENT_CREATION 0x02
00191 #define THREAD_CREATION 0x04
00192 #define UNKNOWN 0x08
00193 #define ILLEGAL_USE_OF_EVENT 0x10
00194 #define MEMORY_FAULT 0x20
00195 DWORD m_dwObjectCondition;
00196 BOOL Push(LPVOID lpv);
00197 BOOL Pop();
00198 BOOL Empty();
00199 public:
00205 CMutexClass m_mutex;
00206
00207 virtual BOOL OnTask(LPVOID lpvData);
00208 virtual BOOL OnTask();
00209
00210 CThread(void);
00211 ~CThread(void);
00212 #ifdef WINDOWS
00213 friend DWORD WINAPI _THKERNEL( LPVOID lpvData );
00214 #else
00215 friend LPVOID _THKERNEL(LPVOID lpvData);
00216 #endif
00217 BOOL KernelProcess();
00218 BOOL Event(LPVOID lpvData=NULL);
00219 BOOL Event(CTask *pvTask);
00220 void Stop();
00221 BOOL Start();
00222 void GetId(ThreadId_t *pId) { memcpy(pId,&m_dwId,sizeof(ThreadId_t)); }
00223 ThreadState_t ThreadState();
00224 BOOL PingThread(DWORD dwTimeout=0);
00225 #ifdef WINDOWS
00226 void SetPriority(DWORD dwPriority=THREAD_PRIORITY_NORMAL);
00227 #else
00228 void SetPriority(DWORD dwPriority=0);
00229 #endif
00230 DWORD GetErrorFlags() { return m_dwObjectCondition; }
00231 void SetThreadType(ThreadType_t typ=ThreadTypeEventDriven,DWORD dwIdle=100);
00232 void SetIdle(DWORD dwIdle=100);
00233 unsigned int GetEventsPending();
00234 static BOOL ThreadIdsEqual(ThreadId_t *p1,
00235 ThreadId_t *p2)
00236 {
00237 #if defined(AS400)||defined(OS400)
00238 return(( memcmp(p1,p2,sizeof(ThreadId_t))==0)?true:false);
00239 #elif defined(VMS)
00240 return (( pthread_equal(*p1,*p2) )?true:false );
00241 #else
00242 return ((*p1 == *p2)?true:false);
00243 #endif
00244
00245 }
00246
00247 static ThreadId_t ThreadId()
00248 {
00249 ThreadId_t thisThreadsId ;
00250 #if defined(AS400) || defined(OS400)
00251 pthread_t thread;
00252 #endif
00253
00254 #ifdef WINDOWS
00255 thisThreadsId = (ThreadId_t)GetCurrentThreadId();
00256 #else
00257
00258 #if defined(AS400) || defined(OS400)
00259 thread = pthread_self();
00260 pthread_getunique_np(&thread,&thisThreadsId);
00261 #elif defined(ALPHA) || defined(DEC) || defined(VMS)
00262 #ifdef VMS
00263 thisThreadsId = pthread_self();
00264 #else
00265 thisThreadsId = pthread_getsequence_np(pthread_self());
00266 #endif
00267 #else
00268 thisThreadsId = pthread_self();
00269 #endif
00270 #endif
00271 return thisThreadsId;
00272 }
00273
00274
00275 };
00276 #endif
00277