From: Yingxin Date: Thu, 30 Aug 2018 09:56:24 +0000 (+0800) Subject: crimson/net: support multiple call to conn.close() X-Git-Tag: v14.0.1~408^2~4 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=2d61065bd7312a271fbb4a0958733effcefda357;p=ceph-ci.git crimson/net: support multiple call to conn.close() It is possible while closing a connectin during a msgr shutdown, a second close() can be called in `read_tags_until_next_message()` Signed-off-by: Yingxin --- diff --git a/src/crimson/net/SocketConnection.cc b/src/crimson/net/SocketConnection.cc index 69a729505db..e695e0ac61a 100644 --- a/src/crimson/net/SocketConnection.cc +++ b/src/crimson/net/SocketConnection.cc @@ -330,14 +330,25 @@ seastar::future<> SocketConnection::keepalive() seastar::future<> SocketConnection::close() { + if (state == state_t::closed) { + // already closing + assert(close_ready.valid()); + return close_ready.get_future(); + } + + state = state_t::closed; + // unregister_conn() drops a reference, so hold another until completion auto cleanup = [conn = ConnectionRef(this)] {}; get_messenger()->unregister_conn(this); - return seastar::when_all(in.close(), out.close()) + // close_ready become valid only after state is state_t::closed + assert(!close_ready.valid()); + close_ready = seastar::when_all(in.close(), out.close()) .discard_result() .finally(std::move(cleanup)); + return close_ready.get_future(); } // handshake diff --git a/src/crimson/net/SocketConnection.h b/src/crimson/net/SocketConnection.h index 01c8cb532db..b034685eb84 100644 --- a/src/crimson/net/SocketConnection.h +++ b/src/crimson/net/SocketConnection.h @@ -15,6 +15,7 @@ #pragma once #include +#include #include "msg/Policy.h" #include "Connection.h" @@ -31,6 +32,9 @@ class SocketConnection : public Connection { state_t state = state_t::none; + /// become valid only when state is state_t::closed + seastar::shared_future<> close_ready; + /// buffer state for read() struct Reader { bufferlist buffer;