CodeMover prototype
[dyninst.git] / external / boost / detail / lightweight_thread.hpp
1 #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED\r
2 #define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED\r
3 \r
4 // MS compatible compilers support #pragma once\r
5 \r
6 #if defined(_MSC_VER) && (_MSC_VER >= 1020)\r
7 # pragma once\r
8 #endif\r
9 \r
10 //  boost/detail/lightweight_thread.hpp\r
11 //\r
12 //  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.\r
13 //  Copyright (c) 2008 Peter Dimov\r
14 //\r
15 //  Distributed under the Boost Software License, Version 1.0.\r
16 //  See accompanying file LICENSE_1_0.txt or copy at\r
17 //  http://www.boost.org/LICENSE_1_0.txt\r
18 \r
19 #include <boost/config.hpp>\r
20 #include <memory>\r
21 #include <cerrno>\r
22 \r
23 // pthread_create, pthread_join\r
24 \r
25 #if defined( BOOST_HAS_PTHREADS )\r
26 \r
27 #include <pthread.h>\r
28 \r
29 #else\r
30 \r
31 #include <windows.h>\r
32 #include <process.h>\r
33 \r
34 typedef HANDLE pthread_t;\r
35 \r
36 int pthread_create( pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )\r
37 {\r
38     HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );\r
39 \r
40     if( h != 0 )\r
41     {\r
42         *thread = h;\r
43         return 0;\r
44     }\r
45     else\r
46     {\r
47         return EAGAIN;\r
48     }\r
49 }\r
50 \r
51 int pthread_join( pthread_t thread, void ** /*value_ptr*/ )\r
52 {\r
53     ::WaitForSingleObject( thread, INFINITE );\r
54     ::CloseHandle( thread );\r
55     return 0;\r
56 }\r
57 \r
58 #endif\r
59 \r
60 // template<class F> int lw_thread_create( pthread_t & pt, F f );\r
61 \r
62 namespace boost\r
63 {\r
64 \r
65 namespace detail\r
66 {\r
67 \r
68 class lw_abstract_thread\r
69 {\r
70 public:\r
71 \r
72     virtual ~lw_abstract_thread() {}\r
73     virtual void run() = 0;\r
74 };\r
75 \r
76 #if defined( BOOST_HAS_PTHREADS )\r
77 \r
78 extern "C" void * lw_thread_routine( void * pv )\r
79 {\r
80     std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );\r
81 \r
82     pt->run();\r
83 \r
84     return 0;\r
85 }\r
86 \r
87 #else\r
88 \r
89 unsigned __stdcall lw_thread_routine( void * pv )\r
90 {\r
91     std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );\r
92 \r
93     pt->run();\r
94 \r
95     return 0;\r
96 }\r
97 \r
98 #endif\r
99 \r
100 template<class F> class lw_thread_impl: public lw_abstract_thread\r
101 {\r
102 public:\r
103 \r
104     explicit lw_thread_impl( F f ): f_( f )\r
105     {\r
106     }\r
107 \r
108     void run()\r
109     {\r
110         f_();\r
111     }\r
112 \r
113 private:\r
114 \r
115     F f_;\r
116 };\r
117 \r
118 template<class F> int lw_thread_create( pthread_t & pt, F f )\r
119 {\r
120     std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );\r
121 \r
122     int r = pthread_create( &pt, 0, lw_thread_routine, p.get() );\r
123 \r
124     if( r == 0 )\r
125     {\r
126         p.release();\r
127     }\r
128 \r
129     return r;\r
130 }\r
131 \r
132 } // namespace detail\r
133 } // namespace boost\r
134 \r
135 #endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED\r