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