Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

strand_service.hpp 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. //
  2. // detail/strand_service.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_DETAIL_STRAND_SERVICE_HPP
  11. #define ASIO_DETAIL_STRAND_SERVICE_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include "asio/io_context.hpp"
  17. #include "asio/detail/mutex.hpp"
  18. #include "asio/detail/op_queue.hpp"
  19. #include "asio/detail/operation.hpp"
  20. #include "asio/detail/scoped_ptr.hpp"
  21. #include "asio/detail/push_options.hpp"
  22. namespace asio {
  23. namespace detail {
  24. // Default service implementation for a strand.
  25. class strand_service
  26. : public asio::detail::service_base<strand_service>
  27. {
  28. private:
  29. // Helper class to re-post the strand on exit.
  30. struct on_do_complete_exit;
  31. // Helper class to re-post the strand on exit.
  32. struct on_dispatch_exit;
  33. public:
  34. // The underlying implementation of a strand.
  35. class strand_impl
  36. : public operation
  37. {
  38. public:
  39. strand_impl();
  40. private:
  41. // Only this service will have access to the internal values.
  42. friend class strand_service;
  43. friend struct on_do_complete_exit;
  44. friend struct on_dispatch_exit;
  45. // Mutex to protect access to internal data.
  46. asio::detail::mutex mutex_;
  47. // Indicates whether the strand is currently "locked" by a handler. This
  48. // means that there is a handler upcall in progress, or that the strand
  49. // itself has been scheduled in order to invoke some pending handlers.
  50. bool locked_;
  51. // The handlers that are waiting on the strand but should not be run until
  52. // after the next time the strand is scheduled. This queue must only be
  53. // modified while the mutex is locked.
  54. op_queue<operation> waiting_queue_;
  55. // The handlers that are ready to be run. Logically speaking, these are the
  56. // handlers that hold the strand's lock. The ready queue is only modified
  57. // from within the strand and so may be accessed without locking the mutex.
  58. op_queue<operation> ready_queue_;
  59. };
  60. typedef strand_impl* implementation_type;
  61. // Construct a new strand service for the specified io_context.
  62. ASIO_DECL explicit strand_service(asio::io_context& io_context);
  63. // Destroy all user-defined handler objects owned by the service.
  64. ASIO_DECL void shutdown();
  65. // Construct a new strand implementation.
  66. ASIO_DECL void construct(implementation_type& impl);
  67. // Request the io_context to invoke the given handler.
  68. template <typename Handler>
  69. void dispatch(implementation_type& impl, Handler& handler);
  70. // Request the io_context to invoke the given handler and return immediately.
  71. template <typename Handler>
  72. void post(implementation_type& impl, Handler& handler);
  73. // Determine whether the strand is running in the current thread.
  74. ASIO_DECL bool running_in_this_thread(
  75. const implementation_type& impl) const;
  76. private:
  77. // Helper function to dispatch a handler. Returns true if the handler should
  78. // be dispatched immediately.
  79. ASIO_DECL bool do_dispatch(implementation_type& impl, operation* op);
  80. // Helper fiunction to post a handler.
  81. ASIO_DECL void do_post(implementation_type& impl,
  82. operation* op, bool is_continuation);
  83. ASIO_DECL static void do_complete(void* owner,
  84. operation* base, const asio::error_code& ec,
  85. std::size_t bytes_transferred);
  86. // The io_context implementation used to post completions.
  87. io_context_impl& io_context_;
  88. // Mutex to protect access to the array of implementations.
  89. asio::detail::mutex mutex_;
  90. // Number of implementations shared between all strand objects.
  91. #if defined(ASIO_STRAND_IMPLEMENTATIONS)
  92. enum { num_implementations = ASIO_STRAND_IMPLEMENTATIONS };
  93. #else // defined(ASIO_STRAND_IMPLEMENTATIONS)
  94. enum { num_implementations = 193 };
  95. #endif // defined(ASIO_STRAND_IMPLEMENTATIONS)
  96. // Pool of implementations.
  97. scoped_ptr<strand_impl> implementations_[num_implementations];
  98. // Extra value used when hashing to prevent recycled memory locations from
  99. // getting the same strand implementation.
  100. std::size_t salt_;
  101. };
  102. } // namespace detail
  103. } // namespace asio
  104. #include "asio/detail/pop_options.hpp"
  105. #include "asio/detail/impl/strand_service.hpp"
  106. #if defined(ASIO_HEADER_ONLY)
  107. # include "asio/detail/impl/strand_service.ipp"
  108. #endif // defined(ASIO_HEADER_ONLY)
  109. #endif // ASIO_DETAIL_STRAND_SERVICE_HPP