From a44ca9140940eaef951949e3eaafd2b7d33f112d Mon Sep 17 00:00:00 2001
From: orignal <i2porignal@yandex.ru>
Date: Wed, 17 Dec 2014 15:21:50 -0500
Subject: [PATCH] terminate acceptor and sessions on stop

---
 BOB.cpp |  3 ++-
 SAM.cpp | 30 +++++++++++++++++++++++-------
 SAM.h   | 11 +++++------
 3 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/BOB.cpp b/BOB.cpp
index e4188487..3d271e4e 100644
--- a/BOB.cpp
+++ b/BOB.cpp
@@ -580,9 +580,10 @@ namespace client
 
 	void BOBCommandChannel::Stop ()
 	{
+		m_IsRunning = false;
 		for (auto it: m_Destinations)
 			it.second->Stop ();
-		m_IsRunning = false;
+		m_Acceptor.cancel ();	
 		m_Service.stop ();
 		if (m_Thread)
 		{	
diff --git a/SAM.cpp b/SAM.cpp
index f85b686c..1b66b7c7 100644
--- a/SAM.cpp
+++ b/SAM.cpp
@@ -568,6 +568,24 @@ namespace client
 			LogPrint (eLogWarning, "Datagram size ", len," exceeds buffer");
 	}
 
+	SAMSession::SAMSession (ClientDestination * localDestination)
+	{
+	}
+		
+	SAMSession::~SAMSession ()
+	{
+		for (auto it: sockets)
+			it->SetSocketType (eSAMSocketTypeTerminated);
+		i2p::client::context.DeleteLocalDestination (localDestination);
+	}
+
+	void SAMSession::CloseStreams ()
+	{
+		for (auto it: sockets)
+			it->CloseStream ();
+		sockets.clear ();
+	}
+
 	SAMBridge::SAMBridge (int port):
 		m_IsRunning (false), m_Thread (nullptr),
 		m_Acceptor (m_Service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
@@ -591,6 +609,9 @@ namespace client
 	void SAMBridge::Stop ()
 	{
 		m_IsRunning = false;
+		m_Acceptor.cancel ();
+		m_DatagramSocket.cancel ();
+		m_Sessions.clear ();
 		m_Service.stop ();
 		if (m_Thread)
 		{	
@@ -661,10 +682,8 @@ namespace client
 		}
 		if (localDestination)
 		{
-			SAMSession session;
-			session.localDestination = localDestination;
 			std::unique_lock<std::mutex> l(m_SessionsMutex);
-			auto ret = m_Sessions.insert (std::pair<std::string, SAMSession>(id, session));
+			auto ret = m_Sessions.insert (std::pair<std::string, SAMSession>(id, SAMSession (localDestination)));
 			if (!ret.second)
 				LogPrint ("Session ", id, " already exists");
 			return &(ret.first->second);
@@ -678,10 +697,7 @@ namespace client
 		auto it = m_Sessions.find (id);
 		if (it != m_Sessions.end ())
 		{
-			for (auto it1: it->second.sockets)
-				it1->CloseStream ();
-			it->second.sockets.clear ();
-			i2p::client::context.DeleteLocalDestination (it->second.localDestination);
+			it->second.CloseStreams ();
 			m_Sessions.erase (it);
 		}
 	}
diff --git a/SAM.h b/SAM.h
index f8772112..e4f37259 100644
--- a/SAM.h
+++ b/SAM.h
@@ -131,12 +131,11 @@ namespace client
 	{
 		ClientDestination * localDestination;
 		std::list<std::shared_ptr<SAMSocket> > sockets;
-				
-		~SAMSession ()
-		{
-			for (auto it: sockets)
-				it->SetSocketType (eSAMSocketTypeTerminated);
-		}		
+		
+		SAMSession (ClientDestination * localDestination);		
+		~SAMSession ();
+
+		void CloseStreams ();
 	};
 
 	class SAMBridge