Destroy I2PControlSession before io_service, cancel waiting operations.

This commit is contained in:
EinMByte 2015-08-02 12:57:16 +02:00
parent 9cca01d159
commit c7f4a79b2c
4 changed files with 28 additions and 5 deletions

View File

@ -122,6 +122,17 @@ I2PControlSession::I2PControlSession(boost::asio::io_service& ios)
routerManagerHandlers[I2P_CONTROL_ROUTER_MANAGER_RESEED] = &I2PControlSession::handleReseed; routerManagerHandlers[I2P_CONTROL_ROUTER_MANAGER_RESEED] = &I2PControlSession::handleReseed;
} }
I2PControlSession::~I2PControlSession()
{
stop();
}
void I2PControlSession::stop()
{
boost::system::error_code e; // Make sure this doesn't throw
shutdownTimer.cancel(e);
}
I2PControlSession::Response I2PControlSession::handleRequest(std::stringstream& request) I2PControlSession::Response I2PControlSession::handleRequest(std::stringstream& request)
{ {
boost::property_tree::ptree pt; boost::property_tree::ptree pt;

View File

@ -57,6 +57,7 @@ const char I2P_CONTROL_ROUTER_MANAGER_RESEED[] = "Reseed";
/** /**
* "Null" I2P control implementation, does not do actual networking. * "Null" I2P control implementation, does not do actual networking.
* @note authentication tokens are per-session * @note authentication tokens are per-session
* @warning an I2PControlSession must be destroyed before its io_service
*/ */
class I2PControlSession { class I2PControlSession {
@ -104,10 +105,19 @@ public:
/** /**
* Sets up the appropriate handlers. * Sets up the appropriate handlers.
* @param ios the parent io_service object * @param ios the parent io_service object, must remain valid throughout
* the lifetime of this I2PControlSession.
*/ */
I2PControlSession(boost::asio::io_service& ios); I2PControlSession(boost::asio::io_service& ios);
~I2PControlSession();
/**
* Cancels all operations that are waiting.
* @note must not be called before destruction, destructor handles this
*/
void stop();
/** /**
* Handle a json string with I2PControl instructions. * Handle a json string with I2PControl instructions.
*/ */
@ -120,7 +130,6 @@ private:
const PropertyTree& pt, Response& results const PropertyTree& pt, Response& results
); );
typedef void (I2PControlSession::*RequestHandler)(Response& results); typedef void (I2PControlSession::*RequestHandler)(Response& results);
/** /**
* Tries to authenticate by checking whether the given token is valid. * Tries to authenticate by checking whether the given token is valid.

View File

@ -11,11 +11,12 @@ namespace i2p
namespace client namespace client
{ {
I2PControlService::I2PControlService(const std::string& address, int port) I2PControlService::I2PControlService(const std::string& address, int port)
: m_Session(m_Service), m_IsRunning(false), m_Thread(nullptr), : m_Session(new I2PControlSession(m_Service)), m_IsRunning(false), m_Thread(nullptr),
m_Acceptor(m_Service, boost::asio::ip::tcp::endpoint( m_Acceptor(m_Service, boost::asio::ip::tcp::endpoint(
boost::asio::ip::address::from_string(address), port) boost::asio::ip::address::from_string(address), port)
) )
{ {
} }
I2PControlService::~I2PControlService () I2PControlService::~I2PControlService ()
@ -39,6 +40,8 @@ namespace client
{ {
m_IsRunning = false; m_IsRunning = false;
m_Acceptor.cancel (); m_Acceptor.cancel ();
// Delete the session before the io_service is stopped and destroyed
delete m_Session;
m_Service.stop (); m_Service.stop ();
if (m_Thread) if (m_Thread)
{ {
@ -126,7 +129,7 @@ namespace client
} }
} }
I2PControlSession::Response response = m_Session.handleRequest(ss); I2PControlSession::Response response = m_Session->handleRequest(ss);
SendResponse(socket, buf, response.toJsonString(), isHtml); SendResponse(socket, buf, response.toJsonString(), isHtml);
} }
catch (const std::exception& ex) catch (const std::exception& ex)

View File

@ -48,7 +48,7 @@ private:
boost::asio::io_service m_Service; boost::asio::io_service m_Service;
boost::asio::ip::tcp::acceptor m_Acceptor; boost::asio::ip::tcp::acceptor m_Acceptor;
I2PControlSession m_Session; I2PControlSession* m_Session;
}; };
} }