This commit is contained in:
jolavillette 2026-09-05 04:04:31 +08:00 committed by GitHub
commit fdaa751dcc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 6 deletions

View File

@ -29,6 +29,14 @@ static const std::string kConfigKeyBOBAddr = "BOB_ADDR";
static constexpr bool kDefaultSAM3Enable = false;
/* At least i2pd doesn't like to instantaniously stop and (re)start a session, so
* a new session is never created less than this long after the previous one was
* closed. The wait happens in startSession(), where it is actually needed, and
* not in stopSession(): a stop is not always followed by a start (RS shutdown,
* "stop" button in the settings) and waiting there held back the whole
* application exit by 10 seconds. */
static constexpr auto kSessionRestartDelay = std::chrono::seconds(10);
RS_SET_CONTEXT_DEBUG_LEVEL(2)
static void inline doSleep(std::chrono::duration<long, std::ratio<1,1000>> timeToSleepMS) {
@ -36,7 +44,9 @@ static void inline doSleep(std::chrono::duration<long, std::ratio<1,1000>> timeT
}
p3I2pSam3::p3I2pSam3(p3PeerMgr *peerMgr) :
mConfigLoaded(false), mPeerMgr(peerMgr), mPending(), mLock("p3i2p-sam3")
mConfigLoaded(false), mPeerMgr(peerMgr), mPending(),
mLastSessionClosed(std::chrono::steady_clock::time_point::min()),
mLock("p3i2p-sam3")
#ifdef RS_USE_I2P_SAM3_LIBSAM3
, mLockSam3Access("p3i2p-sam3-access")
#endif
@ -498,6 +508,19 @@ bool p3I2pSam3::startSession()
stopSession();
}
// Give i2pd time to let go of the previous session. No lock may be held here.
std::chrono::steady_clock::time_point sessionReady;
{
RS_STACK_MUTEX(mLock);
sessionReady = mLastSessionClosed + kSessionRestartDelay;
}
const auto now = std::chrono::steady_clock::now();
if (now < sessionReady) {
const auto wait = std::chrono::duration_cast<std::chrono::milliseconds>(sessionReady - now);
RS_DBG("waiting ", wait.count(), " ms before creating a new SAM session");
doSleep(wait);
}
auto session = (Sam3Session*)rs_malloc(sizeof (Sam3Session));
// add nick
@ -592,12 +615,10 @@ void p3I2pSam3::stopSession()
mSetting.session = nullptr;
mState = samStatus::samState::offline;
}
// At least i2pd doesn't like to instantaniously stop and (re)start a session, wait here just a little bit.
// Not ideal but does the trick.
// (This happens when using the "restart" button in the settings.)
doSleep(std::chrono::seconds(10));
// startSession() waits out kSessionRestartDelay counted from here
mLastSessionClosed = std::chrono::steady_clock::now();
}
}
void p3I2pSam3::stopForwarding()

View File

@ -1,6 +1,7 @@
#ifndef P3I2PSAM3_H
#define P3I2PSAM3_H
#include <chrono>
#include <queue>
#include <list>
@ -102,6 +103,10 @@ private:
// used to keep track of connections, libsam3 does it internally but it can be unreliable since pointers are shared
std::list<Sam3Connection *> mValidConnections, mInvalidConnections;
// Point in time at which the last SAM session was closed. startSession() uses
// it to honour kSessionRestartDelay. Guarded by mLock.
std::chrono::steady_clock::time_point mLastSessionClosed;
// mutex
RsMutex mLock;
RsMutex mLockSam3Access; // libsam3 is not thread safe! (except for key lookup)