OSDN Git Service

40a7ae054aaf58dbb149305b3cc0bfd2ec4e1665
[roast/roast.git] / roast / include / roast / std / thread / thread.hpp
1 //      Roast+ License
2
3 /*
4 */
5 #ifndef __SFJP_ROAST__std__thread__thread_HPP__
6 #define __SFJP_ROAST__std__thread__thread_HPP__
7
8 //#include "roast/_common.hpp"
9 #include <string>
10
11 /*typedef int (*thread_func_t)(int);
12 typedef int (*thread_callback_t)(int);
13 typedef void* thread_handle_t;*/
14
15 namespace roast
16 {
17         typedef int (*thread_func_t)(int);
18         typedef int (*thread_callback_t)(int);
19         typedef void* thread_handle_t;
20         
21         ///////////////////////////////////////////////////////
22         
23         class thread_exception : public ::std::string
24         {
25         public:
26                 thread_exception(const char* msg) : ::std::string(msg) {}
27                 thread_exception(const ::std::string &s) : ::std::string(s) {}
28         };
29         
30         /////////////////////////////////////////////////////////////////
31         
32         template <typename _Class, typename _Param, typename _Ret>
33         struct _thread_start_class_info
34         {
35                 typedef _Ret (_Class::*callback_t)(_Param);
36
37                 _Class* instance;
38                 callback_t func;
39                 _Param param;
40                 bool need_instance_delete;
41
42                 _thread_start_class_info(_Class *instance_in, callback_t func_in,
43                         _Param param_in, bool need_instance_delete_in)
44                 :
45                         instance(instance_in), func(func_in),
46                         param(param_in), need_instance_delete(need_instance_delete_in) {}
47         };
48         
49         template <typename _Class>
50         int _thread_class_internal_callback(int start_class_info_ptr)
51         {
52                 _thread_start_class_info<_Class>* p = (_thread_start_class_info<_Class>*)start_class_info_ptr;
53                 int ret = ((p->instance)->*p->func)(p->param);
54                 if ( p->need_instance_delete )
55                         delete p->instance;
56                 delete p;
57                 return ret;
58         }
59
60         ////////////////////////////////////////////////////////////
61
62         template <typename _Impl>
63         class thread_
64         {
65         public:
66                 typedef int (*func_t)(int);
67                 typedef int (*callback_t)(int);
68                 typedef void* handle_t;
69         protected:
70                 _Impl m_impl;
71                 thread_handle_t m_handle;
72         public:
73                 thread_(){
74                         m_handle = NULL;
75                 }
76                 
77                 /*thread_(thread_func_t func, int param=0, void* opt=NULL)
78                 {
79                         if ( start(func,param,opt) != true )
80                                 thread_exception("thread start failed.");
81                 }*/
82                 template <typename _Func, typename _Param>
83                 thread_(_Func func, _Param param=0, void* opt=NULL)
84                 {
85                         if ( start(func,param,opt) != true )
86                                 thread_exception("thread start failed.");
87                 }
88                 
89 //#ifndef _ROAST_INVALID_TEMPLATE_OVERLOAD
90                 template <typename _Class, typename _Param, typename _Ret>
91                 thread_(_Class* p_this, _Ret (_Class::*func)(_Param), _Param param=0, void* opt=NULL)
92                 {
93                         if ( start_class_ptr(p_this,func,param,opt) != true )
94                                 thread_exception("thread start failed.");
95                 }
96 //#endif
97                 virtual ~thread_()
98                 {
99                         release();
100                 }
101
102                 ////////////////////////////////////////////////////////
103                 
104                 bool start(thread_func_t func, int param=0, void* opt=NULL)
105                 {
106                         return start_func(func,param,opt);
107                 }
108
109 #ifndef _ROAST_INVALID_TEMPLATE_OVERLOAD
110                 template <typename _Param, typename _Ret>
111                 bool start(_Ret (*func)(_Param), _Param param=0, void* opt=NULL)
112                 {
113                         return start_func(func,param,opt);
114                 }
115
116                 /*
117                 template <typename _Class, typename _Param>
118                 bool start(_Class *ptr, _Param param=0, void* opt=NULL)
119                 {
120                         return start_class_ptr(ptr,param,opt);
121                 }*/
122
123                 template <typename _Class, typename _Param, typename _Ret>
124                 bool start(_Ret (__thiscall _Class::*func)(_Param), _Param param=0, void* opt=NULL)
125                 {
126                         //  The second parameter is a class pointer or the method should be static.
127                         The_second_parameter_is_a_class_pointer_or_the_method_should_be_static.
128                 }
129
130                 template <typename _Class, typename _Param>
131                 bool start(_Class &cls, _Param param=0, void* opt=NULL)
132                 {
133                         return start_class(cls,param,opt);
134                 }
135
136                 template <typename _Class, typename _Param, typename _Ret>
137                 bool start(_Class *p_this, _Ret (_Class::*func)(_Param), _Param param=0, void* opt=NULL)
138                 {
139                         return start_class_ptr(p_this,func,param,opt);
140                 }
141 #endif
142
143                 ////////////////////////////////////////////////////////
144
145                 bool start_func(thread_func_t func, int param=0, void* opt=NULL)
146                 {
147                         m_handle = m_impl.start(func,param,opt);
148                         if ( m_handle == NULL )
149                                 return false;
150                         else
151                                 return true;
152                 }
153
154                 template <typename _Param, typename _Ret>
155                 bool start_func(_Ret (*func)(_Param), _Param param=0, void* opt=NULL)
156                 {
157                         m_handle = m_impl.start((thread_func_t)func,(int)param,opt);
158                         if ( m_handle == NULL )
159                                 return false;
160                         else
161                                 return true;
162                 }
163
164                 template <typename _Class, typename _Param>
165                 bool start_class(_Class &cls, _Param param=0, void* opt=NULL)
166                 {
167                         m_handle = m_impl.start(
168                                 _thread_class_internal_callback<_Class>,
169                                 (int)new _thread_start_class_info<_Class>(new _Class(cls), &_Class::operator(), param, true),
170                                 opt);
171                         if ( m_handle == NULL )
172                                 return false;
173                         else
174                                 return true;
175                 }
176
177                 /*
178                 template <typename _Class, typename _Param>
179                 bool start_class_ptr(_Class *p_this, _Param param=0, void* opt=NULL)
180                 {
181                         m_handle = m_impl.start(
182                                 _thread_class_internal_callback<_Class>,
183                                 (int)new _thread_start_class_info<_Class>(p_this, &_Class::operator(), param, false),
184                                 opt);
185                         if ( m_handle == NULL )
186                                 return false;
187                         else
188                                 return true;
189                 }
190
191                 template <typename _Class, typename _Param, typename _Ret>
192                 bool start_class_ptr(_Ret (_Class::*func)(_Param), _Param param=0, void* opt=NULL)
193                 {
194                         //  The second parameter is a class pointer or the method should be static.
195                         The_second_parameter_is_a_class_pointer_or_the_method_should_be_static.
196                 }
197                 */
198
199                 template <typename _Class, typename _Param, typename _Ret>
200                 bool start_class_ptr(_Class *p_this, _Ret (_Class::*func)(_Param), _Param param=0, void* opt=NULL)
201                 {
202                         m_handle = m_impl.start(
203                                 _thread_class_internal_callback<_Class>,
204                                 (int)new _thread_start_class_info<_Class>(p_this, func, param, false),
205                                 opt);
206                         if ( m_handle == NULL )
207                                 return false;
208                         else
209                                 return true;
210                 }
211
212                 ////////////////////////////////////////////////////
213
214                 bool release()
215                 {
216                         if ( m_handle != NULL )
217                                 return m_impl.release(m_handle);
218                         return true;
219                 }
220                 bool join(unsigned int timeout_ms=-1)
221                 {
222                         if ( m_handle == NULL )
223                                 return false;
224                         return m_impl.join(m_handle, timeout_ms);
225                 }
226                 bool is_alive()
227                 {
228                         if ( m_handle == NULL )
229                                 return false;
230                         return m_impl.is_alive(m_handle);
231                 }
232                 int get_result()
233                 {
234                         return m_impl.get_result(m_handle);
235                 }
236                 
237                 void* get_native_handle(){ return m_handle; }
238         };
239         
240         ///////////////////////////////////////
241 }
242
243 #ifdef WIN32
244         #include "roast/windows/thread_impl.hpp"
245 #endif//WIN32
246
247 #endif//__SFJP_ROAST__std__thread__thread_HPP__