File indexing completed on 2025-09-18 09:04:54
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" inline void * lw_thread_routine( void * pv )
0108 {
0109 std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
0110
0111 pt->run();
0112
0113 return 0;
0114 }
0115
0116 #else
0117
0118 inline unsigned __stdcall lw_thread_routine( void * pv )
0119 {
0120 std::unique_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
0121
0122 pt->run();
0123
0124 return 0;
0125 }
0126
0127 #endif
0128
0129 template<class F> class lw_thread_impl: public lw_abstract_thread
0130 {
0131 public:
0132
0133 explicit lw_thread_impl( F f ): f_( f )
0134 {
0135 }
0136
0137 void run()
0138 {
0139 f_();
0140 }
0141
0142 private:
0143
0144 F f_;
0145 };
0146
0147 template<class F> int lw_thread_create( lw_thread_t & th, F f )
0148 {
0149 std::unique_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
0150
0151 int r = lw_thread_create_( &th, 0, lw_thread_routine, p.get() );
0152
0153 if( r == 0 )
0154 {
0155 p.release();
0156 }
0157
0158 return r;
0159 }
0160
0161 }
0162 }
0163
0164 #endif