sprint 1-alpha
|
00001 /****************************************************************************** 00002 * SPRINT::thread 00003 * 00004 * Copyright (C) 2003-2011 Paolo Medici <www.pmx.it> 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 * 00020 *******************************************************************************/ 00021 00027 #ifndef _THREAD_H 00028 #define _THREAD_H 00029 00030 #include <sprint/thread/detail/platform.h> 00031 #include <sprint/thread/detail/function.h> 00032 00033 #if defined SPRINT_THREAD_WIN32 00034 00035 namespace sprint { 00036 00043 class thread { 00044 HANDLE hThread; 00045 DWORD dwThreadId; 00046 00047 private: 00049 thread(const thread & src) { } 00050 00051 public: 00052 00054 thread() : hThread(INVALID_HANDLE_VALUE), dwThreadId(0) {} 00055 00056 ~thread() 00057 { 00058 if(hThread != INVALID_HANDLE_VALUE) 00059 ::CloseHandle(hThread); 00060 } 00061 00062 00068 inline bool create_thread(const sprint::thread_function & p) 00069 { 00070 hThread = ::CreateThread(NULL, 00071 0, 00072 p.proc, 00073 p.param, 00074 0, 00075 &dwThreadId); 00076 return hThread != INVALID_HANDLE_VALUE; 00077 } 00078 00079 00082 inline bool get_exit_code(LPDWORD lpdwExitCode) 00083 { 00084 return ::GetExitCodeThread(hThread, lpdwExitCode)!=0; 00085 } 00086 00089 inline bool is_terminated() const 00090 { 00091 if(hThread==INVALID_HANDLE_VALUE) return true; 00092 return ::WaitForSingleObject(hThread, 0) == WAIT_OBJECT_0 ; 00093 } 00094 00097 inline bool is_running() const 00098 { 00099 if(hThread==INVALID_HANDLE_VALUE) return false; 00100 return ::WaitForSingleObject(hThread, 0) != WAIT_OBJECT_0 ; 00101 } 00102 00105 inline bool kill() 00106 { 00107 return ::TerminateThread(hThread, 0)!=0; 00108 } 00109 00111 bool join(unsigned int timeout = INFINITE) 00112 { 00113 return ::WaitForSingleObject(hThread, timeout) == WAIT_OBJECT_0 ; 00114 } 00115 00116 }; 00117 00131 class runnable: public thread { 00132 00133 // jump method 00134 static DWORD __stdcall CALLBACK _thread_proc(void *p) 00135 { 00136 return (DWORD) (reinterpret_cast<runnable*>(p))->the_thread(); 00137 } 00138 00139 public: 00140 00142 virtual void * the_thread() = 0; 00143 00144 virtual ~runnable() { } 00145 00147 void run() 00148 { 00149 thread::create_thread(sprint::thread_function(_thread_proc, reinterpret_cast<void*>(this)) ); 00150 } 00151 00152 }; 00153 00154 00155 } // sprint 00156 00157 #elif defined SPRINT_THREAD_POSIX 00158 00159 #include <pthread.h> 00160 00161 namespace sprint { 00162 00163 class thread { 00164 pthread_t m_thread; 00165 private: 00167 thread(const thread & src) { } 00168 public: 00169 00170 public: 00171 00173 thread() {} 00174 00175 ~thread() 00176 { 00177 } 00178 00180 inline bool create_thread(const sprint::thread_function & p) 00181 { 00182 int ret = pthread_create(&m_thread, 0, 00183 p.proc, 00184 p.param); 00185 } 00186 00188 inline bool kill() const 00189 { 00190 // TODO 00191 return false; 00192 } 00193 00195 bool join() const 00196 { 00197 return pthread_join(m_thread, 0); 00198 } 00199 00200 }; 00201 00202 class runnable: public thread { 00203 00204 static void * _thread_proc(void *p) 00205 { 00206 return (void *) (reinterpret_cast<runnable*>(p))->the_thread(); 00207 } 00208 00209 public: 00210 virtual void * the_thread() = 0; 00211 00212 virtual ~runnable() { } 00213 00215 void run() 00216 { 00217 thread::create_thread(sprint::thread_function(_thread_proc, reinterpret_cast<void*>(this)) ); 00218 } 00219 }; 00220 00221 } 00222 00223 #endif 00224 00225 00226 00227 #endif