11#include " stream.h"
22#include " connection.h"
3+ #include " endpoint.h"
34#include " log.h"
5+ #include " uvw/async.h"
46
57#include < cassert>
68#include < iostream>
@@ -46,13 +48,19 @@ std::ostream& operator<<(std::ostream& o, const StreamID& s) {
4648 return o << u8" Str❰" << s.id << u8" ❱" ;
4749}
4850
49- Stream::Stream (Connection& conn, data_callback_t data_cb, close_callback_t close_cb, size_t buffer_size)
50- : conn{conn}, data_callback{std::move (data_cb)}, close_callback{std::move (close_cb)}, buffer{buffer_size}
51+ Stream::Stream (Connection& conn, data_callback_t data_cb, close_callback_t close_cb, size_t buffer_size, StreamID id) :
52+ conn{conn},
53+ stream_id{std::move (id)},
54+ data_callback{std::move (data_cb)},
55+ close_callback{std::move (close_cb)},
56+ buffer{buffer_size},
57+ avail_trigger{conn.endpoint .get_loop ().resource <uvw::AsyncHandle>()}
5158{
59+ avail_trigger->on <uvw::AsyncEvent>([this ] (auto &, auto &) { handle_unblocked (); });
5260}
5361
5462Stream::Stream (Connection& conn, StreamID id, size_t buffer_size)
55- : conn {conn}, stream_id{id}, buffer{ buffer_size}
63+ : Stream {conn, nullptr , nullptr , buffer_size, std::move (id) }
5664{
5765}
5866
@@ -122,7 +130,7 @@ void Stream::acknowledge(size_t bytes) {
122130 size -= bytes;
123131 start = size == 0 ? 0 : (start + bytes) % buffer.size (); // reset start to 0 (to reduce wrapping buffers) if empty
124132 if (!unblocked_callbacks.empty ())
125- handle_unblocked ();
133+ available_ready ();
126134}
127135
128136std::pair<bstring_view, bstring_view> Stream::pending () {
@@ -140,26 +148,24 @@ std::pair<bstring_view, bstring_view> Stream::pending() {
140148}
141149
142150void Stream::when_available (unblocked_callback_t unblocked_cb) {
151+ assert (available () == 0 );
143152 unblocked_callbacks.push (std::move (unblocked_cb));
144- handle_unblocked ();
145153}
146154
147155void Stream::handle_unblocked () {
148156 while (!unblocked_callbacks.empty () && available () > 0 ) {
149- #ifndef NDEBUG
150- size_t pre_avail = available ();
151- #endif
152- bool done = unblocked_callbacks.front ()(*this );
153- if (done)
157+ if (unblocked_callbacks.front ()(*this ))
154158 unblocked_callbacks.pop ();
155159 else
156- assert (available () < pre_avail );
160+ assert (available () == 0 );
157161 }
158162 conn.io_ready ();
159163}
160164
161165void Stream::io_ready () { conn.io_ready (); }
162166
167+ void Stream::available_ready () { avail_trigger->send (); }
168+
163169void Stream::wrote (size_t bytes) {
164170 // Called to tell us we sent some bytes off, e.g. wrote(3) changes:
165171 // [ áaarrrrrr ] or [rr áaar]
0 commit comments