Fix incorrect socket closure in Overlay peers:

On Application exit, Overlay was calling PeerImp::close for each peer.
The implementation of PeerImp::close only canceled all pending I/O and did not
call functions necessary for proper transition of Peer state during socket
closure. The correct transition is ensured by calling PeerImp::detach. This
changes PeerImp::close to call PeerImp::detach instead, ensuring that Overlay
invariants are maintained. Specifically, that reference counts for pending I/O
on peers will be correctly unwound by canceling operations and that the Peer
object will be destroyed, thus allowing the Overlay to stop correctly.
This commit is contained in:
Vinnie Falco
2014-10-24 13:43:22 -07:00
parent 1e37a5509c
commit 6564f6c164
2 changed files with 38 additions and 45 deletions

View File

@@ -111,6 +111,42 @@ public:
~OverlayImpl ();
PeerSequence
getActivePeers () override;
Peer::ptr
findPeerByShortID (Peer::ShortId const& id) override;
/** Process an incoming connection using the Peer protocol.
The caller transfers ownership of the socket via rvalue move.
@param socket A socket in the accepted state.
*/
void
accept (socket_type&& socket);
Peer::ShortId
next_id();
void
remove (PeerFinder::Slot::ptr const& slot);
/** Called when a peer has connected successfully
This is called after the peer handshake has been completed and during
peer activation. At this point, the peer address and the public key
are known.
*/
void
activate (Peer::ptr const& peer);
/** A peer is being disconnected
This is called during the disconnection of a known, activated peer. It
will not be called for outbound peer connections that don't succeed or
for connections of peers that are dropped prior to being activated.
*/
void
onPeerDisconnect (Peer::ptr const& peer);
private:
OverlayImpl (OverlayImpl const&) = delete;
OverlayImpl& operator= (OverlayImpl const&) = delete;
@@ -123,34 +159,11 @@ public:
Json::Value
json() override;
PeerSequence
getActivePeers () override;
Peer::ptr
findPeerByShortID (Peer::ShortId const& id) override;
public:
/** Process an incoming connection using the Peer protocol.
The caller transfers ownership of the socket via rvalue move.
@param socket A socket in the accepted state.
*/
void
accept (socket_type&& socket);
Peer::ShortId
next_id();
//--------------------------------------------------------------------------
void
check_stopped ();
void
release ();
void
remove (PeerFinder::Slot::ptr const& slot);
//
// Stoppable
//
@@ -184,23 +197,9 @@ public:
//--------------------------------------------------------------------------
/** Called when a peer has connected successfully
This is called after the peer handshake has been completed and during
peer activation. At this point, the peer address and the public key
are known.
*/
void
activate (Peer::ptr const& peer);
release();
/** A peer is being disconnected
This is called during the disconnection of a known, activated peer. It
will not be called for outbound peer connections that don't succeed or
for connections of peers that are dropped prior to being activated.
*/
void
onPeerDisconnect (Peer::ptr const& peer);
private:
void
sendpeers();

View File

@@ -83,13 +83,7 @@ PeerImp::start ()
void
PeerImp::close()
{
if (! strand_.running_in_this_thread())
return strand_.post (std::bind (
&PeerImp::close, shared_from_this()));
error_code ec;
timer_.cancel(ec);
stream_.next_layer().close(ec);
detach("close", false);
}
//------------------------------------------------------------------------------