lightweight_thread.hpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED
  2. #define BOOST_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 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. #include <boost/config.hpp>
  16. #include <memory>
  17. #include <cerrno>
  18. // pthread_create, pthread_join
  19. #if defined( BOOST_HAS_PTHREADS )
  20. #include <pthread.h>
  21. #else
  22. #include <windows.h>
  23. #include <process.h>
  24. typedef HANDLE pthread_t;
  25. int pthread_create( pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg )
  26. {
  27. HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 );
  28. if( h != 0 )
  29. {
  30. *thread = h;
  31. return 0;
  32. }
  33. else
  34. {
  35. return EAGAIN;
  36. }
  37. }
  38. int pthread_join( pthread_t thread, void ** /*value_ptr*/ )
  39. {
  40. ::WaitForSingleObject( thread, INFINITE );
  41. ::CloseHandle( thread );
  42. return 0;
  43. }
  44. #endif
  45. // template<class F> int lw_thread_create( pthread_t & pt, F f );
  46. namespace boost
  47. {
  48. namespace detail
  49. {
  50. class lw_abstract_thread
  51. {
  52. public:
  53. virtual ~lw_abstract_thread() {}
  54. virtual void run() = 0;
  55. };
  56. #if defined( BOOST_HAS_PTHREADS )
  57. extern "C" void * lw_thread_routine( void * pv )
  58. {
  59. std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
  60. pt->run();
  61. return 0;
  62. }
  63. #else
  64. unsigned __stdcall lw_thread_routine( void * pv )
  65. {
  66. std::auto_ptr<lw_abstract_thread> pt( static_cast<lw_abstract_thread *>( pv ) );
  67. pt->run();
  68. return 0;
  69. }
  70. #endif
  71. template<class F> class lw_thread_impl: public lw_abstract_thread
  72. {
  73. public:
  74. explicit lw_thread_impl( F f ): f_( f )
  75. {
  76. }
  77. void run()
  78. {
  79. f_();
  80. }
  81. private:
  82. F f_;
  83. };
  84. template<class F> int lw_thread_create( pthread_t & pt, F f )
  85. {
  86. std::auto_ptr<lw_abstract_thread> p( new lw_thread_impl<F>( f ) );
  87. int r = pthread_create( &pt, 0, lw_thread_routine, p.get() );
  88. if( r == 0 )
  89. {
  90. p.release();
  91. }
  92. return r;
  93. }
  94. } // namespace detail
  95. } // namespace boost
  96. #endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED