lightweight_thread.hpp 3.4 KB

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