8 struct channel_impl :
public std::enable_shared_from_this<channel_impl<_Ty>>
10 typedef _awaker<channel_impl<_Ty>, _Ty*, error_code> channel_read_awaker;
11 typedef std::shared_ptr<channel_read_awaker> channel_read_awaker_ptr;
13 typedef _awaker<channel_impl<_Ty>> channel_write_awaker;
14 typedef std::shared_ptr<channel_write_awaker> channel_write_awaker_ptr;
15 typedef std::pair<channel_write_awaker_ptr, _Ty> write_tuple_type;
18 typedef std::recursive_mutex lock_type;
21 const size_t _max_counter;
22 std::deque<_Ty> _values;
23 std::list<channel_read_awaker_ptr> _read_awakes;
24 std::list<write_tuple_type> _write_awakes;
26 channel_impl(
size_t max_counter_)
27 :_max_counter(max_counter_)
32 const std::deque<_Ty>& debug_queue()
const
38 template<
class callee_t,
class = std::enable_if<!std::is_same<std::remove_cv_t<callee_t>, channel_read_awaker_ptr>::value>>
39 decltype(
auto) read(callee_t&& awaker)
41 return read_(std::make_shared<channel_read_awaker>(std::forward<callee_t>(awaker)));
43 template<
class callee_t,
class _Ty2,
class = std::enable_if<!std::is_same<std::remove_cv_t<callee_t>, channel_write_awaker_ptr>::value>>
44 decltype(
auto) write(callee_t&& awaker, _Ty2&& val)
46 return write_(std::make_shared<channel_write_awaker>(std::forward<callee_t>(awaker)), std::forward<_Ty2>(val));
51 bool read_(channel_read_awaker_ptr&& r_awaker)
55 scoped_lock<lock_type> lock_(this->_lock);
58 if (_values.size() > 0)
61 auto val = std::move(_values.front());
64 r_awaker->awake(
this, 1, &val, error_code::none);
70 _read_awakes.push_back(r_awaker);
82 void write_(channel_write_awaker_ptr&& w_awaker, _Ty2&& val)
85 scoped_lock<lock_type> lock_(this->_lock);
88 bool is_full = _values.size() >= _max_counter;
90 _write_awakes.push_back(std::make_pair(std::forward<channel_write_awaker_ptr>(w_awaker), std::forward<_Ty2>(val)));
92 _values.push_back(std::forward<_Ty2>(val));
98 if (!is_full) w_awaker->awake(
this, 1);
103 void awake_one_reader_()
107 for (
auto iter = _read_awakes.begin(); iter != _read_awakes.end(); )
109 auto r_awaker = *iter;
110 iter = _read_awakes.erase(iter);
112 if (r_awaker->awake(
this, 1, _values.size() ? &_values.front() :
nullptr, error_code::read_before_write))
114 if (_values.size()) _values.pop_front();
124 void awake_one_writer_()
126 for (
auto iter = _write_awakes.begin(); iter != _write_awakes.end(); )
128 auto w_awaker = std::move(*iter);
129 iter = _write_awakes.erase(iter);
131 if (w_awaker.first->awake(
this, 1))
134 _values.push_back(std::move(w_awaker.second));
140 size_t capacity() const noexcept
145 channel_impl(
const channel_impl&) =
delete;
146 channel_impl(channel_impl&&) =
delete;
147 channel_impl& operator = (
const channel_impl&) =
delete;
148 channel_impl& operator = (channel_impl&&) =
delete;
158 typedef detail::channel_impl<_Ty> channel_impl_type;
159 typedef typename channel_impl_type::channel_read_awaker channel_read_awaker;
160 typedef typename channel_impl_type::channel_write_awaker channel_write_awaker;
162 typedef std::shared_ptr<channel_impl_type> channel_impl_ptr;
163 typedef std::weak_ptr<channel_impl_type> channel_impl_wptr;
164 typedef std::chrono::system_clock clock_type;
166 channel_impl_ptr _chan;
168 channel_t(
size_t max_counter = 0)
169 :_chan(std::make_shared<channel_impl_type>(max_counter))
175 future_t<bool> write(_Ty2&& val)
const
177 awaitable_t<bool> awaitable;
179 auto awaker = std::make_shared<channel_write_awaker>(
180 [st = awaitable._state](channel_impl_type* chan) ->
bool
182 st->set_value(chan ? true : false);
185 _chan->write_(std::move(awaker), std::forward<_Ty2>(val));
187 return awaitable.get_future();
190 future_t<_Ty> read()
const
192 awaitable_t<_Ty> awaitable;
194 auto awaker = std::make_shared<channel_read_awaker>(
195 [st = awaitable._state](channel_impl_type*, _Ty* val, error_code fe) ->
bool
198 st->set_value(std::move(*val));
200 st->throw_exception(channel_exception{ fe });
204 _chan->read_(std::move(awaker));
206 return awaitable.get_future();
210 future_t<bool> operator << (_Ty2&& val)
const
212 return std::move(write(std::forward<_Ty2>(val)));
215 future_t<_Ty>
operator co_await ()
const
222 const auto& debug_queue()
const
224 return _chan->debug_queue();
228 size_t capacity() const noexcept
230 return _chan->capacity();
233 channel_t(
const channel_t&) =
default;
234 channel_t(channel_t&&) =
default;
235 channel_t& operator = (
const channel_t&) =
default;
236 channel_t& operator = (channel_t&&) =
default;
240 using semaphore_t = channel_t<bool>;