]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 |