bool LocalNode::_cmdDisconnect( Command& command ) { EQASSERT( _inReceiverThread( )); const NodeDisconnectPacket* packet = command.get< NodeDisconnectPacket >(); NodePtr node = static_cast<Node*>( getRequestData( packet->requestID )); EQASSERT( node.isValid( )); ConnectionPtr connection = node->_outgoing; if( connection.isValid( )) { node->_state = STATE_CLOSED; node->_outgoing = 0; _removeConnection( connection ); EQASSERT( _connectionNodes.find( connection )!=_connectionNodes.end( )); _objectStore->removeInstanceData( node->_id ); _connectionNodes.erase( connection ); { base::ScopedMutex< base::SpinLock > mutex( _nodes ); _nodes->erase( node->_id ); } EQINFO << node << " disconnected from " << this << " connection used " << connection->getRefCount() << std::endl; } EQASSERT( node->_state == STATE_CLOSED ); serveRequest( packet->requestID ); return true; }
void LocalNode::_handleDisconnect() { while( _handleData( )) ; // read remaining data off connection ConnectionPtr connection = _incoming.getConnection(); ConnectionNodeHash::iterator i = _connectionNodes.find( connection ); if( i != _connectionNodes.end( )) { NodePtr node = i->second; Command& command = _commandCache.alloc( node, this, sizeof( NodeRemoveNodePacket )); NodeRemoveNodePacket* packet = command.getModifiable< NodeRemoveNodePacket >(); *packet = NodeRemoveNodePacket(); packet->node = node.get(); _dispatchCommand( command ); if( node->_outgoing == connection ) { _objectStore->removeInstanceData( node->_id ); _connectionNodes.erase( i ); node->_state = STATE_CLOSED; node->_outgoing = 0; if( node->_outMulticast.data.isValid( ) ) _removeConnection( node->_outMulticast.data ); node->_outMulticast = 0; node->_multicasts.clear(); EQINFO << node << " disconnected from " << *this << std::endl; base::ScopedMutex< base::SpinLock > mutex( _nodes ); _nodes->erase( node->_id ); } else { EQASSERT( connection->getDescription()->type >= CONNECTIONTYPE_MULTICAST ); base::ScopedMutex<> mutex( _outMulticast ); if( node->_outMulticast == connection ) node->_outMulticast = 0; else { for( MCDatas::iterator j = node->_multicasts.begin(); j != node->_multicasts.end(); ++j ) { if( (*j).connection != connection ) continue; node->_multicasts.erase( j ); break; } } } } _removeConnection( connection ); EQINFO << "connection used " << connection->getRefCount() << std::endl; }