wait_group.hpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //
  2. // Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 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. #ifndef BOOST_MYSQL_IMPL_INTERNAL_CONNECTION_POOL_WAIT_GROUP_HPP
  8. #define BOOST_MYSQL_IMPL_INTERNAL_CONNECTION_POOL_WAIT_GROUP_HPP
  9. #include <boost/mysql/error_code.hpp>
  10. #include <boost/asio/any_io_executor.hpp>
  11. #include <boost/asio/bind_executor.hpp>
  12. #include <boost/asio/steady_timer.hpp>
  13. #include <chrono>
  14. #include <cstddef>
  15. namespace boost {
  16. namespace mysql {
  17. namespace detail {
  18. class wait_group
  19. {
  20. std::size_t running_tasks_{};
  21. asio::steady_timer finished_;
  22. public:
  23. wait_group(asio::any_io_executor ex)
  24. : finished_(std::move(ex), (std::chrono::steady_clock::time_point::max)())
  25. {
  26. }
  27. asio::any_io_executor get_executor() { return finished_.get_executor(); }
  28. void on_task_start() noexcept { ++running_tasks_; }
  29. void on_task_finish() noexcept
  30. {
  31. if (--running_tasks_ == 0u)
  32. finished_.cancel(); // If this happens to fail, terminate() is the best option
  33. }
  34. // Note: this operation always completes with a cancelled error code
  35. // (for simplicity).
  36. template <class CompletionToken>
  37. void async_wait(CompletionToken&& token)
  38. {
  39. return finished_.async_wait(std::forward<CompletionToken>(token));
  40. }
  41. // Runs op calling the adequate group member functions when op is started and finished.
  42. // The operation is run within this->get_executor()
  43. template <class Op>
  44. void run_task(Op&& op)
  45. {
  46. on_task_start();
  47. std::forward<Op>(op)(asio::bind_executor(get_executor(), [this](error_code) { on_task_finish(); }));
  48. }
  49. };
  50. } // namespace detail
  51. } // namespace mysql
  52. } // namespace boost
  53. #endif