]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/smart_ptr/detail/lightweight_thread.hpp
867f00b0b733a704dd18e884fee69f3f63cd3c84
[ceph.git] / ceph / src / boost / boost / smart_ptr / detail / lightweight_thread.hpp
1 #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
2 #define BOOST_SMART_PTR_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, 2018 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 //
20 // typedef /*...*/ lw_thread_t; // as pthread_t
21 // template<class F> int lw_thread_create( lw_thread_t & th, F f );
22 // void lw_thread_join( lw_thread_t th );
23
24
25 #include <boost/config.hpp>
26 #include <memory>
27 #include <cerrno>
28
29 #if defined( BOOST_HAS_PTHREADS )
30
31 #include <pthread.h>
32
33 namespace boost
34 {
35 namespace detail
36 {
37
38 typedef ::pthread_t lw_thread_t;
39
40 inline int lw_thread_create_( lw_thread_t* thread, const pthread_attr_t* attr, void* (*start_routine)( void* ), void* arg )
41 {
42 return ::pthread_create( thread, attr, start_routine, arg );
43 }
44
45 inline void lw_thread_join( lw_thread_t th )
46 {
47 ::pthread_join( th, 0 );
48 }
49
50 } // namespace detail
51 } // namespace boost
52
53 #else // defined( BOOST_HAS_PTHREADS )
54
55 #include <windows.h>
56 #include <process.h>
57
58 namespace boost
59 {
60 namespace detail
61 {
62
63 typedef HANDLE lw_thread_t;
64
65 inline int lw_thread_create_( lw_thread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
66 {
67 HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
68
69 if( h != 0 )
70 {
71 *thread = h;
72 return 0;
73 }
74 else
75 {
76 return EAGAIN;
77 }
78 }
79
80 inline void lw_thread_join( lw_thread_t thread )
81 {
82 ::WaitForSingleObject( thread, INFINITE );
83 ::CloseHandle( thread );
84 }
85
86 } // namespace detail
87 } // namespace boost
88
89 #endif // defined( BOOST_HAS_PTHREADS )
90
91
92 namespace boost
93 {
94 namespace detail
95 {
96
97 class lw_abstract_thread
98 {
99 public:
100
101 virtual ~lw_abstract_thread() {}
102 virtual void run() = 0;
103 };
104
105 #if defined( BOOST_HAS_PTHREADS )
106
107 extern "C" void * lw_thread_routine( void * pv )
108 {
109 #if defined(BOOST_NO_CXX11_SMART_PTR)
110
111 std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
112
113 #else
114
115 std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
116
117 #endif
118
119 pt->run();
120
121 return 0;
122 }
123
124 #else
125
126 unsigned __stdcall lw_thread_routine( void * pv )
127 {
128 #if defined(BOOST_NO_CXX11_SMART_PTR)
129
130 std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
131
132 #else
133
134 std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
135
136 #endif
137
138 pt->run();
139
140 return 0;
141 }
142
143 #endif
144
145 template<class F> class lw_thread_impl: public lw_abstract_thread
146 {
147 public:
148
149 explicit lw_thread_impl( F f ): f_( f )
150 {
151 }
152
153 void run()
154 {
155 f_();
156 }
157
158 private:
159
160 F f_;
161 };
162
163 template<class F> int lw_thread_create( lw_thread_t & th, F f )
164 {
165 #if defined(BOOST_NO_CXX11_SMART_PTR)
166
167 std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
168
169 #else
170
171 std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
172
173 #endif
174
175 int r = lw_thread_create_( &th, 0, lw_thread_routine, p.get() );
176
177 if( r == 0 )
178 {
179 p.release();
180 }
181
182 return r;
183 }
184
185 } // namespace detail
186 } // namespace boost
187
188 #endif // #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED