async_base.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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_CORE_IMPL_ASYNC_BASE_HPP
  10. #define BOOST_BEAST_CORE_IMPL_ASYNC_BASE_HPP
  11. #include <boost/core/exchange.hpp>
  12. namespace boost {
  13. namespace beast {
  14. namespace detail {
  15. template<class State, class Allocator>
  16. struct allocate_stable_state final
  17. : stable_base
  18. , boost::empty_value<Allocator>
  19. {
  20. State value;
  21. template<class... Args>
  22. explicit
  23. allocate_stable_state(
  24. Allocator const& alloc,
  25. Args&&... args)
  26. : boost::empty_value<Allocator>(
  27. boost::empty_init_t{}, alloc)
  28. , value{std::forward<Args>(args)...}
  29. {
  30. }
  31. void destroy() override
  32. {
  33. using A = typename allocator_traits<
  34. Allocator>::template rebind_alloc<
  35. allocate_stable_state>;
  36. A a(this->get());
  37. auto* p = this;
  38. p->~allocate_stable_state();
  39. a.deallocate(p, 1);
  40. }
  41. };
  42. } // detail
  43. template<
  44. class Handler,
  45. class Executor1,
  46. class Allocator,
  47. class Function>
  48. void asio_handler_invoke(
  49. Function&& f,
  50. async_base<Handler, Executor1, Allocator>* p)
  51. {
  52. using net::asio_handler_invoke;
  53. asio_handler_invoke(f,
  54. p->get_legacy_handler_pointer());
  55. }
  56. template<
  57. class Handler,
  58. class Executor1,
  59. class Allocator>
  60. void*
  61. asio_handler_allocate(
  62. std::size_t size,
  63. async_base<Handler, Executor1, Allocator>* p)
  64. {
  65. using net::asio_handler_allocate;
  66. return asio_handler_allocate(size,
  67. p->get_legacy_handler_pointer());
  68. }
  69. template<
  70. class Handler,
  71. class Executor1,
  72. class Allocator>
  73. void
  74. asio_handler_deallocate(
  75. void* mem, std::size_t size,
  76. async_base<Handler, Executor1, Allocator>* p)
  77. {
  78. using net::asio_handler_deallocate;
  79. asio_handler_deallocate(mem, size,
  80. p->get_legacy_handler_pointer());
  81. }
  82. template<
  83. class Handler,
  84. class Executor1,
  85. class Allocator>
  86. bool
  87. asio_handler_is_continuation(
  88. async_base<Handler, Executor1, Allocator>* p)
  89. {
  90. using net::asio_handler_is_continuation;
  91. return asio_handler_is_continuation(
  92. p->get_legacy_handler_pointer());
  93. }
  94. template<
  95. class State,
  96. class Handler,
  97. class Executor1,
  98. class Allocator,
  99. class... Args>
  100. State&
  101. allocate_stable(
  102. stable_async_base<
  103. Handler, Executor1, Allocator>& base,
  104. Args&&... args)
  105. {
  106. using allocator_type = typename stable_async_base<
  107. Handler, Executor1, Allocator>::allocator_type;
  108. using state = detail::allocate_stable_state<
  109. State, allocator_type>;
  110. using A = typename detail::allocator_traits<
  111. allocator_type>::template rebind_alloc<state>;
  112. struct deleter
  113. {
  114. allocator_type alloc;
  115. state* ptr;
  116. ~deleter()
  117. {
  118. if(ptr)
  119. {
  120. A a(alloc);
  121. a.deallocate(ptr, 1);
  122. }
  123. }
  124. };
  125. A a(base.get_allocator());
  126. deleter d{base.get_allocator(), a.allocate(1)};
  127. ::new(static_cast<void*>(d.ptr))
  128. state(d.alloc, std::forward<Args>(args)...);
  129. d.ptr->next_ = base.list_;
  130. base.list_ = d.ptr;
  131. return boost::exchange(d.ptr, nullptr)->value;
  132. }
  133. } // beast
  134. } // boost
  135. #endif