Exemplo n.º 1
0
// Close all connections
void ConnectionManager::Shutdown()
{
//	sml::PrintDebug("Shutting down connection manager") ;

	// Stop the thread (and wait until it has stopped)
	if (m_ListenerThread)
	{
		m_ListenerThread->Stop(true) ;

		// Remove the listener
		delete m_ListenerThread ;
		m_ListenerThread = NULL ;
	}

//	sml::PrintDebug("Listener stopped") ;

	// Stop the receiver thread (and wait until is has stopped)
	if (m_ReceiverThread)
	{
		m_ReceiverThread->Stop(true) ;

	//	sml::PrintDebug("Receiver stopped") ;

		// Remove the thread
		delete m_ReceiverThread ;
		m_ReceiverThread = NULL ;
	}

	// Serialize thread access to the connections list
	soar_thread::Lock lock(&m_ConnectionsMutex) ;

	for (ConnectionsIter iter = m_Connections.begin() ; iter != m_Connections.end() ; iter++)
	{
		Connection* pConnection = *iter ;
		pConnection->CloseConnection() ;

		// Remove any events that this connection is listening to
		KernelSML* pKernelSML = static_cast<KernelSML*>(pConnection->GetUserData());
		pKernelSML->RemoveAllListeners(pConnection) ;

		// Not clear that we can just delete connections as we might be inside a connection callback
		// when the shutdown comes.  So for safety, move connections to a closed list instead of deleting.
		// For now this will leak the connection object.  Later if we are confident we can delete this list.
		//delete pConnection ;
		m_ClosedConnections.push_back(pConnection) ;
	}

	m_Connections.clear() ;

	// Now clean up all closed connections.
	for (ConnectionsIter iter = m_ClosedConnections.begin() ; iter != m_ClosedConnections.end() ; iter++)
	{
		Connection* pConnection = *iter ;
		delete pConnection ;
	}
	m_ClosedConnections.clear() ;

//	sml::PrintDebug("Completed shutdown") ;
}
Exemplo n.º 2
0
// Go through all connections and read any incoming commands from the sockets.
// The messages are sent to the callback registered with the connection when it was created (ReceivedCall currently).
// Those calls could take a long time to execute (e.g. a call to Run Soar).
// Returns true if we received at least one message.
bool ConnectionManager::ReceiveAllMessages()
{
	int index = 0 ;
	bool receivedOneMessage = false ;

	// We need to search this list of connections and call each in turn.
	// But we also want to allow the listener thread to add new connections while we're doing this.
	// (E.g. we might want to attach a debugger to a process that's already executing a "run" command inside "receiveMessages").
	// So we use this slightly cumbersome approach of looking up the connection based on an integer index.
	// The lookup is thread safe and if the connection list changes between lookups that's fine as this function
	// will return NULL once we go out of bounds.  (You could argue that we might miss calling a connection on a particular pass using this method
	// but that should be ok).
	Connection* pConnection = GetConnectionByIndex(index++) ;

	while (pConnection)
	{
		// Check to see if this connection has already been closed
		// (which includes if the other side has dropped its half of the socket)
		if (!pConnection->IsClosed())
		{
			receivedOneMessage = pConnection->ReceiveMessages(true) || receivedOneMessage ;
		}
		else
		{
			// If the connection has closed, delete it from the list of active connections
			RemoveConnection(pConnection) ;
			
			// Remove any events that this connection is listening to
			KernelSML* pKernelSML = static_cast<KernelSML*>(pConnection->GetUserData());
			pKernelSML->RemoveAllListeners(pConnection) ;

			// Not clear that we can just delete connections as we might be inside a connection callback
			// when the shutdown comes.  So for safety, move connections to a closed list instead of deleting.
			// For now this will leak the connection object.  Later if we are confident we can delete this list.
			//delete pConnection ;
			m_ClosedConnections.push_back(pConnection) ;

			// Since we just removed this connection we should look up the same index value again
			// so we don't skip any.  This isn't really that important.
			index-- ;
		}

		// Get the next connection (will return NULL once we reach the end of the list)
		pConnection = GetConnectionByIndex(index++) ;
	}

	// So far we don't have some sort of shutdown message the remote connections
	// can send, but if we decide to implement it this allows us to return it.
	return receivedOneMessage ;
}