Thread.h
Go to the documentation of this file.
00001 //
00002 // Thread.h: header file
00003 //
00004 // Copyright (C) Walter E. Capers.  All rights reserved
00005 //
00006 // This source is free to use as you like.  If you make
00007 // any changes please keep me in the loop.  Email them to
00008 // walt.capers@comcast.net.
00009 //
00010 // PURPOSE:
00011 //
00012 //  To implement Win32 threading as a C++ object
00013 //
00014 // REVISIONS
00015 // =======================================================
00016 // Date: 10.24.07        
00017 // Name: Walter E. Capers
00018 // Description: File creation
00019 //
00020 // Date: 10.24.07 11:49 am
00021 // Name: Walter E. Capers
00022 // Description: Added SetIdle function to allow the idle time to be altered
00023 //              independent of the SetThreadType member function.
00024 // Date:
00025 // Name:
00026 // Description:
00027 //
00028 //
00029 
00030 #ifndef THREAD_CLASS
00031 #define THREAD_CLASS
00032 
00033 #ifndef WINDOWS
00034 #if defined(WIN32) || defined(WIN64)
00035 #define WINDOWS
00036 #endif
00037 #endif
00038 
00039 #ifndef WINDOWS
00040 #include <stdio.h>
00041 #include <malloc.h>
00042 #include <memory.h>
00043 #include <pthread.h>
00044 #include <stdlib.h>
00045 #include <time.h>
00046 #include <errno.h>
00047 typedef unsigned char BOOL;
00048 #ifndef TRUE
00049 #define TRUE 1
00050 #endif
00051 #ifndef FALSE
00052 #define FALSE 0
00053 #endif
00054 typedef long DWORD;
00055 typedef void *LPVOID;
00056 #else
00057 #include "afx.h"
00058 #include <windows.h>
00059 #include <stdio.h>
00060 #endif
00061 
00062 
00063 #if defined(AS400) || defined(OS400)
00064 typedef pthread_id_np_t ThreadId_t;
00065 #elif defined(VMS) 
00066 typedef pthread_t ThreadId_t;
00067 #else
00068 typedef DWORD ThreadId_t;
00069 #endif
00070 
00071 #include <blort/ThreadObject/MutexClass.h>
00072 #include <blort/ThreadObject/EventClass.h>
00073 
00074 #define QUE_SIZE 100
00075 #define DEFAULT_STACK_SIZE 0
00076 #ifndef WINDOWS
00077 void Sleep( unsigned int mseconds);
00078 #endif
00079 
00080 typedef enum {
00081         ThreadStateBusy,               // thread is currently handling a task
00082         ThreadStateWaiting,            // thread is waiting for something to do
00083     ThreadStateDown,               // thread is not running
00084     ThreadStateShuttingDown,       // thread is in the process of shutting down
00085     ThreadStateFault               // an error has occured and the thread could not
00086                                        // be launched
00087 } ThreadState_t;
00088 
00089 typedef enum {
00090         ThreadTypeEventDriven,
00091         ThreadTypeIntervalDriven } ThreadType_t;
00092 
00093 typedef enum {
00094         TaskStatusNotSubmitted,
00095         TaskStatusWaitingOnQueue,
00096         TaskStatusBeingProcessed,
00097         TaskStatusCompleted } TaskStatus_t;
00098 
00099 class CTask
00100 {
00101 private:
00102         TaskStatus_t m_state;
00103         ThreadId_t m_dwThread;
00104 public:
00105         CMutexClass m_mutex;
00106 
00107         void SetTaskStatus(TaskStatus_t state) 
00108         {
00109                 m_mutex.Lock();
00110                         m_state=state;
00111                 m_mutex.Unlock();
00112         }
00113 
00114         void SetId(ThreadId_t *pid)
00115         {
00116                 memcpy(&m_dwThread,pid,sizeof(ThreadId_t));
00117         }
00118 
00126         BOOL Wait(int timeoutSeconds)
00127         {
00128         timeoutSeconds = timeoutSeconds * 1000;
00129                 if( Status() != TaskStatusCompleted &&
00130                         timeoutSeconds > 0 )
00131                 {
00132                         Sleep(100);
00133                         timeoutSeconds = timeoutSeconds - 100;
00134                 }
00135                 if( Status() == TaskStatusCompleted ) return TRUE;
00136                 return FALSE;
00137         }
00138 
00145         TaskStatus_t Status()
00146         {
00147                 TaskStatus_t state ;
00148 
00149                 m_mutex.Lock();
00150                   state = m_state;
00151                 m_mutex.Unlock();
00152             return state;
00153         }
00154 
00155         void Thread(ThreadId_t *pId)
00156         {
00157                 memcpy(pId,&m_dwThread,sizeof(ThreadId_t));
00158         }
00159 
00160         CTask(){m_state=TaskStatusNotSubmitted; memset(&m_dwThread,0,sizeof(ThreadId_t)); }
00161         ~CTask(){}
00162         virtual BOOL Task()=0;
00163 };
00164 
00165 
00166 class CThread 
00167 #ifdef WINDOWS
00168         : public CObject // use CObject as a base class so object can be used in lists and
00169                        // object arrays
00170 #endif
00171 {
00172 private:
00173         CEventClass   m_event;         // event controller
00174 
00175         BOOL              m_bRunning;      // set to TRUE if thread is running
00176 #ifdef WINDOWS
00177         HANDLE            m_thread;                // thread handle
00178 #else
00179         pthread_t     m_thread;        // thread handle
00180 #endif
00181         ThreadId_t        m_dwId;          // id of this thread
00182         LPVOID        *m_lppvQue;      // task que
00183         unsigned int  m_chQue;         // que depth
00184         unsigned int  m_quePos;        // current que possition
00185         LPVOID        m_lpvProcessor;  // data which is currently being processed
00186         ThreadState_t m_state;         // current state of thread see thread state data
00187                                        // structure.
00188         DWORD         m_dwIdle;        // used for Sleep periods
00189         ThreadType_t  m_type;
00190         DWORD             m_stackSize;     // thread stack size
00191 #define NO_ERRORS                              0
00192 #define MUTEX_CREATION                 0x01
00193 #define EVENT_CREATION                 0x02
00194 #define THREAD_CREATION                0x04
00195 #define UNKNOWN                                    0x08
00196 #define ILLEGAL_USE_OF_EVENT       0x10
00197 #define MEMORY_FAULT               0x20
00198         DWORD         m_dwObjectCondition;
00199         BOOL              Push(LPVOID lpv);
00200         BOOL              Pop();
00201         BOOL              Empty();
00202 public:
00208         CMutexClass       m_mutex;         // mutex that protects threads internal data
00209 
00210         virtual BOOL OnTask(LPVOID lpvData);     // called when an event occurs
00211         virtual BOOL OnTask();                   // called when a time interval has elapsed
00212 
00213         CThread(void);
00214         ~CThread(void);
00215 #ifdef WINDOWS
00216         friend DWORD WINAPI _THKERNEL( LPVOID lpvData );
00217 #else
00218         friend LPVOID _THKERNEL(LPVOID lpvData);
00219 #endif
00220         BOOL            KernelProcess();
00221         BOOL            Event(LPVOID lpvData=NULL);
00222         BOOL        Event(CTask *pvTask);
00223         void            Stop();
00224         BOOL            Start();
00225         void            GetId(ThreadId_t *pId) { memcpy(pId,&m_dwId,sizeof(ThreadId_t)); }      // returns thread id
00226         ThreadState_t ThreadState();
00227         BOOL            PingThread(DWORD dwTimeout=0);
00228 #ifdef WINDOWS
00229         void            SetPriority(DWORD dwPriority=THREAD_PRIORITY_NORMAL);
00230 #else
00231         void            SetPriority(DWORD dwPriority=0);
00232 #endif
00233         DWORD           GetErrorFlags() { return m_dwObjectCondition; } // returns state of object
00234         void            SetThreadType(ThreadType_t typ=ThreadTypeEventDriven,DWORD dwIdle=100);
00235         void            SetIdle(DWORD dwIdle=100);
00236     unsigned int GetEventsPending();
00237     static BOOL ThreadIdsEqual(ThreadId_t *p1,
00238                                                        ThreadId_t *p2)
00239         {
00240 #if defined(AS400)||defined(OS400)
00241                 return(( memcmp(p1,p2,sizeof(ThreadId_t))==0)?TRUE:FALSE);
00242 #elif defined(VMS) 
00243                 return (( pthread_equal(*p1,*p2) )?TRUE:FALSE );
00244 #else
00245                 return ((*p1 == *p2)?TRUE:FALSE);
00246 #endif
00247 
00248         }
00249 
00250         static ThreadId_t ThreadId()
00251         {
00252                 ThreadId_t thisThreadsId ;
00253 #if defined(AS400) || defined(OS400)
00254                 pthread_t thread;
00255 #endif
00256 
00257 #ifdef WINDOWS
00258                 thisThreadsId = (ThreadId_t)GetCurrentThreadId();
00259 #else
00260 
00261 #if defined(AS400) || defined(OS400)
00262                 thread = pthread_self();
00263                 pthread_getunique_np(&thread,&thisThreadsId);
00264 #elif defined(ALPHA) || defined(DEC) || defined(VMS)
00265 #ifdef VMS
00266                 thisThreadsId = pthread_self();
00267 #else
00268                 thisThreadsId = pthread_getsequence_np(pthread_self());
00269 #endif
00270 #else
00271                 thisThreadsId = pthread_self();
00272 #endif
00273 #endif
00274                 return thisThreadsId;
00275         }
00276 
00277 
00278 };
00279 #endif
00280 


blort
Author(s): Michael Zillich, Thomas Mörwald, Johann Prankl, Andreas Richtsfeld, Bence Magyar (ROS version)
autogenerated on Thu Jan 2 2014 11:38:26