mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2026-10-22 11:42:25 +00:00
stop a destination on its own thread whoever calls it
This commit is contained in:
1 parent
b6be65d774
commit
2352ebffab
2 files changed
+31
-14
No files matched your search
+29
-14
@@ -1155,6 +1155,34 @@ namespace client
|
||||
}
|
||||
|
||||
void ClientDestination::Stop ()
|
||||
{
|
||||
// Stop may be called from any thread, while the service thread is still
|
||||
// inside handlers of this destination, so the teardown goes there. A
|
||||
// stopped service would never run it, in that case there is nobody left
|
||||
// to race with and it is done right here
|
||||
auto& service = GetService ();
|
||||
if (!service.stopped () && !service.get_executor ().running_in_this_thread ())
|
||||
{
|
||||
// the promise is shared because the wait below is bounded: a service
|
||||
// stopped right after the check would never run the handler, and a
|
||||
// stack promise would be gone by then
|
||||
auto done = std::make_shared<std::promise<void> >();
|
||||
auto future = done->get_future ();
|
||||
boost::asio::post (service, [this, done]()
|
||||
{
|
||||
StopInternal ();
|
||||
done->set_value ();
|
||||
});
|
||||
if (future.wait_for (std::chrono::seconds (STOP_ON_SERVICE_TIMEOUT)) == std::future_status::ready)
|
||||
return;
|
||||
LogPrint (eLogError, "Destination: Service didn't stop the destination in ",
|
||||
STOP_ON_SERVICE_TIMEOUT, " seconds");
|
||||
return;
|
||||
}
|
||||
StopInternal ();
|
||||
}
|
||||
|
||||
void ClientDestination::StopInternal ()
|
||||
{
|
||||
LogPrint(eLogDebug, "Destination: Stopping destination ", GetIdentHash().ToBase32(), ".b32.i2p");
|
||||
m_ReadyChecker.cancel();
|
||||
@@ -1692,20 +1720,7 @@ namespace client
|
||||
{
|
||||
if (IsRunning ())
|
||||
{
|
||||
// the destination's own thread may still be handling packets of this
|
||||
// very destination, so tear it down there rather than under the caller
|
||||
if (GetIOService ().get_executor ().running_in_this_thread ())
|
||||
ClientDestination::Stop ();
|
||||
else
|
||||
{
|
||||
std::promise<void> done;
|
||||
boost::asio::post (GetIOService (), [this, &done]()
|
||||
{
|
||||
ClientDestination::Stop ();
|
||||
done.set_value ();
|
||||
});
|
||||
done.get_future ().wait ();
|
||||
}
|
||||
ClientDestination::Stop (); // takes care of the thread it runs on
|
||||
StopIOService ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace client
|
||||
const int PUBLISH_VERIFICATION_TIMEOUT_VARIANCE = 3; // in seconds
|
||||
const int PUBLISH_MIN_INTERVAL = 20; // in seconds
|
||||
const int PUBLISH_REGULAR_VERIFICATION_INTERNAL = 100; // in seconds periodically
|
||||
const int STOP_ON_SERVICE_TIMEOUT = 10; // in seconds, how long Stop waits for the destination's thread
|
||||
const int LEASESET_REQUEST_TIMEOUT = 1200; // in milliseconds
|
||||
const int MAX_LEASESET_REQUEST_TIMEOUT = 17000; // in milliseconds
|
||||
const int DESTINATION_CLEANUP_TIMEOUT = 44; // in seconds
|
||||
@@ -260,6 +261,7 @@ namespace client
|
||||
|
||||
void Start () override;
|
||||
void Stop () override;
|
||||
void StopInternal (); // the teardown itself, always on the destination's thread
|
||||
|
||||
const i2p::data::PrivateKeys& GetPrivateKeys () const { return m_Keys; };
|
||||
void SetPrivateKeys (const i2p::data::PrivateKeys& keys);
|
||||
|
||||
Reference in new issue
Block a user