From: Yingxin Cheng Date: Sat, 12 Oct 2019 07:39:00 +0000 (+0800) Subject: crimson/net: don't fail when nothing queued for sweep X-Git-Tag: v15.1.0~1210^2~5 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=7907ae9bfa077cfd73f83127269955d1c8099602;p=ceph-ci.git crimson/net: don't fail when nothing queued for sweep Fix a corner case when write is dispatching but the queued events are cleared by a remote reset. Signed-off-by: Yingxin Cheng --- diff --git a/src/crimson/net/Protocol.cc b/src/crimson/net/Protocol.cc index fc0d73d2e64..1fad3a499d3 100644 --- a/src/crimson/net/Protocol.cc +++ b/src/crimson/net/Protocol.cc @@ -171,14 +171,39 @@ void Protocol::ack_writes(seq_num_t seq) } } +seastar::future Protocol::try_exit_sweep() { + assert(!is_queued()); + return socket->flush().then([this] { + if (!is_queued()) { + // still nothing pending to send after flush, + // the dispatching can ONLY stop now + ceph_assert(write_dispatching); + write_dispatching = false; + if (unlikely(exit_open.has_value())) { + exit_open->set_value(); + exit_open = std::nullopt; + logger().info("{} write_event: nothing queued at {}," + " set exit_open", + conn, get_state_name(write_state)); + } + return seastar::make_ready_future(stop_t::yes); + } else { + // something is pending to send during flushing + return seastar::make_ready_future(stop_t::no); + } + }); +} + seastar::future<> Protocol::do_write_dispatch_sweep() { return seastar::repeat([this] { switch (write_state) { case write_state_t::open: { size_t num_msgs = conn.out_q.size(); - // we must have something to write... - ceph_assert(is_queued()); + bool still_queued = is_queued(); + if (unlikely(!still_queued)) { + return try_exit_sweep(); + } conn.pending_q.clear(); conn.pending_q.swap(conn.out_q); if (!conn.policy.lossy) { @@ -199,26 +224,7 @@ seastar::future<> Protocol::do_write_dispatch_sweep() assert(ack_left >= acked); ack_left -= acked; if (!is_queued()) { - // good, we have nothing pending to send now. - return socket->flush().then([this] { - if (!is_queued()) { - // still nothing pending to send after flush, - // the dispatching can ONLY stop now - ceph_assert(write_dispatching); - write_dispatching = false; - if (unlikely(exit_open.has_value())) { - exit_open->set_value(); - exit_open = std::nullopt; - logger().info("{} write_event: nothing queued at {}," - " set exit_open", - conn, get_state_name(write_state)); - } - return seastar::make_ready_future(stop_t::yes); - } else { - // something is pending to send during flushing - return seastar::make_ready_future(stop_t::no); - } - }); + return try_exit_sweep(); } else { // messages were enqueued during socket write return seastar::make_ready_future(stop_t::no); diff --git a/src/crimson/net/Protocol.h b/src/crimson/net/Protocol.h index ea7c5d02949..688b5e3d607 100644 --- a/src/crimson/net/Protocol.h +++ b/src/crimson/net/Protocol.h @@ -144,6 +144,7 @@ class Protocol { // it needs to wait for exit_open until writing is stopped or failed. std::optional> exit_open; + seastar::future try_exit_sweep(); seastar::future<> do_write_dispatch_sweep(); void write_event(); };