thread.hpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. //
  2. // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Official repository: https://github.com/boostorg/beast
  8. //
  9. #ifndef BOOST_BEAST_UNIT_TEST_THREAD_HPP
  10. #define BOOST_BEAST_UNIT_TEST_THREAD_HPP
  11. #include <boost/beast/_experimental/unit_test/suite.hpp>
  12. #include <functional>
  13. #include <thread>
  14. #include <utility>
  15. namespace boost {
  16. namespace beast {
  17. namespace unit_test {
  18. /** Replacement for std::thread that handles exceptions in unit tests. */
  19. class thread
  20. {
  21. private:
  22. suite* s_ = nullptr;
  23. std::thread t_;
  24. public:
  25. using id = std::thread::id;
  26. using native_handle_type = std::thread::native_handle_type;
  27. thread() = default;
  28. thread(thread const&) = delete;
  29. thread& operator=(thread const&) = delete;
  30. thread(thread&& other)
  31. : s_(other.s_)
  32. , t_(std::move(other.t_))
  33. {
  34. }
  35. thread& operator=(thread&& other)
  36. {
  37. s_ = other.s_;
  38. t_ = std::move(other.t_);
  39. return *this;
  40. }
  41. template<class F, class... Args>
  42. explicit
  43. thread(suite& s, F&& f, Args&&... args)
  44. : s_(&s)
  45. {
  46. std::function<void(void)> b =
  47. std::bind(std::forward<F>(f),
  48. std::forward<Args>(args)...);
  49. t_ = std::thread(&thread::run, this,
  50. std::move(b));
  51. }
  52. bool
  53. joinable() const
  54. {
  55. return t_.joinable();
  56. }
  57. std::thread::id
  58. get_id() const
  59. {
  60. return t_.get_id();
  61. }
  62. static
  63. unsigned
  64. hardware_concurrency() noexcept
  65. {
  66. return std::thread::hardware_concurrency();
  67. }
  68. void
  69. join()
  70. {
  71. t_.join();
  72. s_->propagate_abort();
  73. }
  74. void
  75. detach()
  76. {
  77. t_.detach();
  78. }
  79. void
  80. swap(thread& other)
  81. {
  82. std::swap(s_, other.s_);
  83. std::swap(t_, other.t_);
  84. }
  85. private:
  86. void
  87. run(std::function <void(void)> f)
  88. {
  89. try
  90. {
  91. f();
  92. }
  93. catch(suite::abort_exception const&)
  94. {
  95. }
  96. catch(std::exception const& e)
  97. {
  98. s_->fail("unhandled exception: " +
  99. std::string(e.what()));
  100. }
  101. catch(...)
  102. {
  103. s_->fail("unhandled exception");
  104. }
  105. }
  106. };
  107. } // unit_test
  108. } // beast
  109. } // boost
  110. #endif