]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/net: support multiple call to conn.close()
authorYingxin <yingxin.cheng@intel.com>
Thu, 30 Aug 2018 09:56:24 +0000 (17:56 +0800)
committerYingxin <yingxin.cheng@intel.com>
Tue, 4 Sep 2018 10:37:48 +0000 (18:37 +0800)
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 <yingxin.cheng@intel.com>
src/crimson/net/SocketConnection.cc
src/crimson/net/SocketConnection.h

index 69a729505db79ae9c91529a7843c4035ea826513..e695e0ac61a3ef44a0942d82519c1f35e36ddff8 100644 (file)
@@ -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
index 01c8cb532db3803862954aa9d3b39d158db30549..b034685eb8443dc2a01db4a8a5ff40e9f5ddf08f 100644 (file)
@@ -15,6 +15,7 @@
 #pragma once
 
 #include <seastar/core/reactor.hh>
+#include <seastar/core/shared_future.hh>
 
 #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;