thread.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. //
  2. // $Id$
  3. //
  4. #include<__vic/thread.h>
  5. #include<__vic/windows/throw_last_error.h>
  6. #include<exception>
  7. #if __VIC_USE_BEGINTHREADEX
  8. #include<__vic/throw_errno.h>
  9. #include<process.h> // _beginthreadex
  10. #endif
  11. namespace __vic {
  12. //----------------------------------------------------------------------------
  13. thread::~thread()
  14. {
  15. if(joinable() && alive())
  16. {
  17. // Should never be executed!
  18. // Application logic corruption
  19. // Attempting to destruct thread-object with still active thread
  20. std::terminate();
  21. }
  22. }
  23. //----------------------------------------------------------------------------
  24. #if __cpp_rvalue_references
  25. thread &thread::operator=(thread &&o) noexcept
  26. {
  27. if(&o != this)
  28. {
  29. if(joinable() && alive()) std::terminate();
  30. h = o.h;
  31. o.h = 0;
  32. }
  33. return *this;
  34. }
  35. #endif
  36. //----------------------------------------------------------------------------
  37. void thread::start()
  38. {
  39. #if __VIC_USE_BEGINTHREADEX
  40. h = reinterpret_cast<HANDLE>(
  41. ::_beginthreadex(0, 0, __vic_thread_impl_func, this, 0, 0));
  42. if(!h) throw_errno("_beginthreadex");
  43. #else
  44. h = ::CreateThread(0, 0, __vic_thread_impl_func, this, 0, 0);
  45. if(!h) windows::throw_last_error("CreateThread");
  46. #endif
  47. }
  48. //----------------------------------------------------------------------------
  49. void thread::cancel()
  50. {
  51. if(!::TerminateThread(handle(), DWORD(-1)))
  52. windows::throw_last_error("TerminateThread");
  53. h = 0;
  54. }
  55. //----------------------------------------------------------------------------
  56. void thread::join()
  57. {
  58. h.Wait();
  59. //DWORD res;
  60. //if(!::GetExitCodeThread(handle(), &res))
  61. // windows::throw_last_error("GetExitCodeThread");
  62. h.Close();
  63. h = 0;
  64. }
  65. //----------------------------------------------------------------------------
  66. bool thread::alive() const
  67. {
  68. DWORD res;
  69. if(!::GetExitCodeThread(handle(), &res))
  70. windows::throw_last_error("GetExitCodeThread");
  71. return res == STILL_ACTIVE;
  72. }
  73. //----------------------------------------------------------------------------
  74. __VIC_THREAD_RETURNTYPE __vic_thread_impl_func(void *that)
  75. {
  76. static_cast<thread *>(that)->worker();
  77. return 0;
  78. }
  79. //----------------------------------------------------------------------------
  80. } // namespace