Subversion Repositories HomeAutomation

Rev

Rev 270 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 270 Rev 800
1
#ifndef __THREAD_H__
1
#ifndef __THREAD_H__
2
#define __THREAD_H__
2
#define __THREAD_H__
3
 
3
 
4
class CThread
4
class CThread
5
{
5
{
6
public:
6
public:
7
        /*
7
        /*
8
         *  Info: Default Constructor
8
         *  Info: Default Constructor
9
         */
9
         */
10
        CThread()
10
        CThread()
11
        {
11
        {
12
            m_pThreadFunc = CThread::EntryPoint; // Can call Detach() also.
12
            m_pThreadFunc = CThread::EntryPoint; // Can call Detach() also.
13
        }
13
        }
14
 
14
 
15
        /*
15
        /*
16
         *  Info: Plug Constructor
16
         *  Info: Plug Constructor
17
         *
17
         *
18
         *  Use this to migrate/port existing worker threads to objects immediately
18
         *  Use this to migrate/port existing worker threads to objects immediately
19
         *  Although you lose the benefits of ThreadCTOR and ThreadDTOR.
19
         *  Although you lose the benefits of ThreadCTOR and ThreadDTOR.
20
         */
20
         */
21
        CThread(LPTHREAD_START_ROUTINE lpExternalRoutine)
21
        CThread(LPTHREAD_START_ROUTINE lpExternalRoutine)
22
        {
22
        {
23
            Attach(lpExternalRoutine);
23
            Attach(lpExternalRoutine);
24
        }
24
        }
25
 
25
 
26
        /*
26
        /*
27
         *  Info: Default Destructor
27
         *  Info: Default Destructor
28
         *
28
         *
29
         *  I think it is wise to destroy the thread even if it is running,
29
         *  I think it is wise to destroy the thread even if it is running,
30
         *  when the main thread reaches here.
30
         *  when the main thread reaches here.
31
         */
31
         */
32
        ~CThread()
32
        ~CThread()
33
        {
33
        {
34
            if ( m_ThreadCtx.m_hThread )
34
            if ( m_ThreadCtx.m_hThread )
35
                Stop(true);
35
                Stop(true);
36
        }
36
        }
37
        /*
37
        /*
38
         *  Info: Starts the thread.
38
         *  Info: Starts the thread.
39
         * 
39
         * 
40
         *  This function starts the thread pointed by m_pThreadFunc with default attributes
40
         *  This function starts the thread pointed by m_pThreadFunc with default attributes
41
         */
41
         */
42
        DWORD Start( void* arg = NULL )
42
        DWORD Start( void* arg = NULL )
43
        {
43
        {
44
            m_ThreadCtx.m_pUserData = arg;
44
            m_ThreadCtx.m_pUserData = arg;
45
            m_ThreadCtx.m_hThread = CreateThread(NULL, 0, m_pThreadFunc, this, 0, &m_ThreadCtx.m_dwTID);
45
            m_ThreadCtx.m_hThread = CreateThread(NULL, 0, m_pThreadFunc, this, 0, &m_ThreadCtx.m_dwTID);
46
            m_ThreadCtx.m_dwExitCode = (DWORD)-1;
46
            m_ThreadCtx.m_dwExitCode = (DWORD)-1;
47
 
47
 
48
            return GetLastError();
48
            return GetLastError();
49
        }
49
        }
50
 
50
 
51
        /*
51
        /*
52
         *  Info: Stops the thread.
52
         *  Info: Stops the thread.
53
         * 
53
         * 
54
         *  This function stops the current thread.
54
         *  This function stops the current thread.
55
         *  We can force kill a thread which results in a TerminateThread.
55
         *  We can force kill a thread which results in a TerminateThread.
56
         */
56
         */
57
        DWORD Stop ( bool bForceKill = false )
57
        DWORD Stop ( bool bForceKill = false )
58
        {
58
        {
59
            if ( m_ThreadCtx.m_hThread )
59
            if ( m_ThreadCtx.m_hThread )
60
            {
60
            {
61
                GetExitCodeThread(m_ThreadCtx.m_hThread, &m_ThreadCtx.m_dwExitCode);
61
                GetExitCodeThread(m_ThreadCtx.m_hThread, &m_ThreadCtx.m_dwExitCode);
62
 
62
 
63
                if ( m_ThreadCtx.m_dwExitCode == STILL_ACTIVE && bForceKill )
63
                if ( m_ThreadCtx.m_dwExitCode == STILL_ACTIVE && bForceKill )
64
                    TerminateThread(m_ThreadCtx.m_hThread, DWORD(-1));
64
                    TerminateThread(m_ThreadCtx.m_hThread, DWORD(-1));
65
 
65
 
66
                m_ThreadCtx.m_hThread = NULL;
66
                m_ThreadCtx.m_hThread = NULL;
67
            }
67
            }
68
 
68
 
69
            return m_ThreadCtx.m_dwExitCode;
69
            return m_ThreadCtx.m_dwExitCode;
70
        }
70
        }
71
 
71
 
72
        /*
72
        /*
73
         *  Info: Starts the thread.
73
         *  Info: Starts the thread.
74
         * 
74
         * 
75
         *  This function starts the thread pointed by m_pThreadFunc with default attributes
75
         *  This function starts the thread pointed by m_pThreadFunc with default attributes
76
         */
76
         */
77
        DWORD GetExitCode() const
77
        DWORD GetExitCode() const
78
        {
78
        {
79
            if ( m_ThreadCtx.m_hThread )
79
            if ( m_ThreadCtx.m_hThread )
80
                GetExitCodeThread(m_ThreadCtx.m_hThread, (LPDWORD)&m_ThreadCtx.m_dwExitCode);
80
                GetExitCodeThread(m_ThreadCtx.m_hThread, (LPDWORD)&m_ThreadCtx.m_dwExitCode);
81
            return m_ThreadCtx.m_dwExitCode;
81
            return m_ThreadCtx.m_dwExitCode;
82
        }
82
        }
83
 
83
 
84
        /*
84
        /*
85
         *  Info: Attaches a Thread Function
85
         *  Info: Attaches a Thread Function
86
         * 
86
         * 
87
         *  Used primarily for porting but can serve in developing generic thread objects
87
         *  Used primarily for porting but can serve in developing generic thread objects
88
         */
88
         */
89
        void Attach( LPTHREAD_START_ROUTINE lpThreadFunc ){
89
        void Attach( LPTHREAD_START_ROUTINE lpThreadFunc ){
90
            m_pThreadFunc = lpThreadFunc;
90
            m_pThreadFunc = lpThreadFunc;
91
        }
91
        }
92
 
92
 
93
        /*
93
        /*
94
         *  Info: Detaches the Attached Thread Function
94
         *  Info: Detaches the Attached Thread Function
95
         * 
95
         * 
96
         *  Detaches the Attached Thread Function, If any.
96
         *  Detaches the Attached Thread Function, If any.
97
         *  by resetting the thread function pointer to EntryPoint1
97
         *  by resetting the thread function pointer to EntryPoint1
98
         */
98
         */
99
        void  Detach( void ){
99
        void  Detach( void ){
100
            m_pThreadFunc = CThread::EntryPoint;
100
            m_pThreadFunc = CThread::EntryPoint;
101
        }
101
        }
102
 
102
 
103
protected:
103
protected:
104
 
104
 
105
        /*
105
        /*
106
         *  Info: DONT override this method.
106
         *  Info: DONT override this method.
107
         * 
107
         * 
108
         *  This function is like a standard template.
108
         *  This function is like a standard template.
109
         *  Override if you are sure of what you are doing.
109
         *  Override if you are sure of what you are doing.
110
         */
110
         */
111
        static DWORD WINAPI EntryPoint( LPVOID pArg)
111
        static DWORD WINAPI EntryPoint( LPVOID pArg)
112
        {
112
        {
113
            CThread *pParent = reinterpret_cast<CThread*>(pArg);
113
            CThread *pParent = reinterpret_cast<CThread*>(pArg);
114
 
114
 
115
            pParent->ThreadCtor();
115
            pParent->ThreadCtor();
116
 
116
 
117
            pParent->Run( pParent->m_ThreadCtx.m_pUserData );
117
            pParent->Run( pParent->m_ThreadCtx.m_pUserData );
118
 
118
 
119
            pParent->ThreadDtor();
119
            pParent->ThreadDtor();
120
 
120
 
121
            return STILL_ACTIVE;
121
            return STILL_ACTIVE;
122
        }
122
        }
123
       
123
       
124
        /*
124
        /*
125
         *  Info: Override this method.
125
         *  Info: Override this method.
126
         * 
126
         * 
127
         *  This function should contain the body/code of your thread.
127
         *  This function should contain the body/code of your thread.
128
         *  Notice the signature is similar to that of any worker thread function
128
         *  Notice the signature is similar to that of any worker thread function
129
         *  except for the calling convention.
129
         *  except for the calling convention.
130
         */
130
         */
131
        virtual DWORD Run( LPVOID /* arg */ )
131
        virtual DWORD Run( LPVOID /* arg */ )
132
        { return m_ThreadCtx.m_dwExitCode; }
132
        { return m_ThreadCtx.m_dwExitCode; }
133
 
133
 
134
        /*
134
        /*
135
         *  Info: Constructor-like function.
135
         *  Info: Constructor-like function.
136
         * 
136
         * 
137
         *  Will be called by EntryPoint before executing the thread body.
137
         *  Will be called by EntryPoint before executing the thread body.
138
         *  Override this function to provide your extra initialization.
138
         *  Override this function to provide your extra initialization.
139
         *
139
         *
140
         *  NOTE: do not confuse it with the classes constructor
140
         *  NOTE: do not confuse it with the classes constructor
141
         */
141
         */
142
        virtual void ThreadCtor(){  }
142
        virtual void ThreadCtor(){  }
143
 
143
 
144
        /*
144
        /*
145
         *  Info: Destructor-like function.
145
         *  Info: Destructor-like function.
146
         * 
146
         * 
147
         *  Will be called by EntryPoint after executing the thread body.
147
         *  Will be called by EntryPoint after executing the thread body.
148
         *  Override this function to provide your extra destruction.
148
         *  Override this function to provide your extra destruction.
149
         *
149
         *
150
         *  NOTE: do not confuse it with the classes constructor
150
         *  NOTE: do not confuse it with the classes constructor
151
         */
151
         */
152
        virtual void ThreadDtor(){  }
152
        virtual void ThreadDtor(){  }
153
       
153
       
154
private:
154
private:
155
        /*
155
        /*
156
         *  Info: Thread Context Inner Class
156
         *  Info: Thread Context Inner Class
157
         * 
157
         * 
158
         *  Every thread object needs to be associated with a set of values.
158
         *  Every thread object needs to be associated with a set of values.
159
         *  like UserData Pointer, Handle, Thread ID etc.
159
         *  like UserData Pointer, Handle, Thread ID etc.
160
         *  
160
         *  
161
         *  NOTE: This class can be enhanced to varying functionalities
161
         *  NOTE: This class can be enhanced to varying functionalities
162
         *        eg.,
162
         *        eg.,
163
         *              * Members to hold StackSize
163
         *              * Members to hold StackSize
164
         *              * SECURITY_ATTRIBUTES member.
164
         *              * SECURITY_ATTRIBUTES member.
165
         */
165
         */
166
        class CThreadContext
166
        class CThreadContext
167
        {
167
        {
168
        public:
168
        public:
169
            CThreadContext(){
169
            CThreadContext(){
170
                memset(this, 0, sizeof(this));
170
                memset(this, 0, sizeof(this));
171
            }
171
            }
172
 
172
 
173
            /*
173
            /*
174
             *  Attributes Section
174
             *  Attributes Section
175
             */
175
             */
176
        public:
176
        public:
177
            HANDLE m_hThread;                   //  The Thread Handle
177
            HANDLE m_hThread;                   //  The Thread Handle
178
            DWORD  m_dwTID;                     //  The Thread ID
178
            DWORD  m_dwTID;                     //  The Thread ID
179
            LPVOID m_pUserData;                     //  The user data pointer
179
            LPVOID m_pUserData;                     //  The user data pointer
180
            LPVOID m_pParent;                   //  The this pointer of the parent CThread object
180
            LPVOID m_pParent;                   //  The this pointer of the parent CThread object
181
            DWORD  m_dwExitCode;                //  The Exit Code of the thread
181
            DWORD  m_dwExitCode;                //  The Exit Code of the thread
182
        };
182
        };
183
 
183
 
184
        /*
184
        /*
185
         *  Attributes Section
185
         *  Attributes Section
186
         */
186
         */
187
protected:
187
protected:
188
        /*
188
        /*
189
         *  Info: Members of CThread
189
         *  Info: Members of CThread
190
         */
190
         */
191
        CThreadContext          m_ThreadCtx;    //  The Thread Context member
191
        CThreadContext          m_ThreadCtx;    //  The Thread Context member
192
        LPTHREAD_START_ROUTINE  m_pThreadFunc;  //  The Worker Thread Function Pointer
192
        LPTHREAD_START_ROUTINE  m_pThreadFunc;  //  The Worker Thread Function Pointer
193
};
193
};
194
 
194
 
195
#endif //__THREAD_H__
195
#endif //__THREAD_H__
196
 
196