File indexing completed on 2025-01-18 09:51:42
0001 #ifndef BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
0002 #define BOOST_SMART_PTR_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
0003
0004
0005
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <boost/config.hpp>
0026 #include <memory>
0027 #include <cerrno>
0028
0029 #if defined( BOOST_HAS_PTHREADS )
0030
0031 #include <pthread.h>
0032
0033 namespace boost
0034 {
0035 namespace detail
0036 {
0037
0038 typedef ::pthread_t lw_thread_t;
0039
0040 inline int lw_thread_create_( lw_thread_t* thread, const pthread_attr_t* attr, void* (*start_routine)( void* ), void* arg )
0041 {
0042 return ::pthread_create( thread, attr, start_routine, arg );
0043 }
0044
0045 inline void lw_thread_join( lw_thread_t th )
0046 {
0047 ::pthread_join( th, 0 );
0048 }
0049
0050 }
0051 }
0052
0053 #else
0054
0055 #include <windows.h>
0056 #include <process.h>
0057
0058 namespace boost
0059 {
0060 namespace detail
0061 {
0062
0063 typedef HANDLE lw_thread_t;
0064
0065 inline int lw_thread_create_( lw_thread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
0066 {
0067 HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
0068
0069 if( h != 0 )
0070 {
0071 *thread = h;
0072 return 0;
0073 }
0074 else
0075 {
0076 return EAGAIN;
0077 }
0078 }
0079
0080 inline void lw_thread_join( lw_thread_t thread )
0081 {
0082 ::WaitForSingleObject( thread, INFINITE );
0083 ::CloseHandle( thread );
0084 }
0085
0086 }
0087 }
0088
0089 #endif
0090
0091
0092 namespace boost
0093 {
0094 namespace detail
0095 {
0096
0097 class lw_abstract_thread
0098 {
0099 public:
0100
0101 virtual ~lw_abstract_thread() {}
0102 virtual void run() = 0;
0103 };
0104
0105 #if defined( BOOST_HAS_PTHREADS )
0106
0107 extern "C" void * lw_thread_routine( void * pv )
0108 {
0109 #if defined(BOOST_NO_CXX11_SMART_PTR)
0110
0111 std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
0112
0113 #else
0114
0115 std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
0116
0117 #endif
0118
0119 pt->run();
0120
0121 return 0;
0122 }
0123
0124 #else
0125
0126 unsigned __stdcall lw_thread_routine( void * pv )
0127 {
0128 #if defined(BOOST_NO_CXX11_SMART_PTR)
0129
0130 std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
0131
0132 #else
0133
0134 std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
0135
0136 #endif
0137
0138 pt->run();
0139
0140 return 0;
0141 }
0142
0143 #endif
0144
0145 template<class F> class lw_thread_impl: public lw_abstract_thread
0146 {
0147 public:
0148
0149 explicit lw_thread_impl( F f ): f_( f )
0150 {
0151 }
0152
0153 void run()
0154 {
0155 f_();
0156 }
0157
0158 private:
0159
0160 F f_;
0161 };
0162
0163 template<class F> int lw_thread_create( lw_thread_t & th, F f )
0164 {
0165 #if defined(BOOST_NO_CXX11_SMART_PTR)
0166
0167 std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
0168
0169 #else
0170
0171 std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
0172
0173 #endif
0174
0175 int r = lw_thread_create_( &th, 0, lw_thread_routine, p.get() );
0176
0177 if( r == 0 )
0178 {
0179 p.release();
0180 }
0181
0182 return r;
0183 }
0184
0185 }
0186 }
0187
0188 #endif