OSDN Git Service

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