adding safe guard for skipping dead locked sessions

This commit is contained in:
Dario 2019-12-07 09:23:55 +01:00
parent f849abc386
commit c9ee1d9178
3 changed files with 61 additions and 10 deletions

View File

@ -147,8 +147,12 @@ Session* SessionManager::getNewSession(int* handle)
int local_handle = mEmptyRequestStack.top(); int local_handle = mEmptyRequestStack.top();
mEmptyRequestStack.pop(); mEmptyRequestStack.pop();
auto resultIt = mRequestSessionMap.find(local_handle); auto resultIt = mRequestSessionMap.find(local_handle);
if (resultIt != mRequestSessionMap.end() && !resultIt->second->isActive()) { if (resultIt != mRequestSessionMap.end()) {
Session* result = resultIt->second; Session* result = resultIt->second;
// check if dead locked
if (result->tryLock()) {
result->unlock();
if (!result->isActive()) {
result->reset(); result->reset();
//mWorkingMutex.unlock(); //mWorkingMutex.unlock();
@ -159,6 +163,16 @@ Session* SessionManager::getNewSession(int* handle)
return result; return result;
} }
} }
else {
ErrorList errors;
errors.addError(new Error("SessionManager::getNewSession", "found dead locked session, keeping in memory without reference"));
errors.sendErrorsAsEmail();
mRequestSessionMap.erase(local_handle);
}
}
}
// else create new RequestSession Object // else create new RequestSession Object
// calculate random handle // calculate random handle
@ -207,10 +221,30 @@ bool SessionManager::releaseSession(int requestHandleSession)
return false; return false;
} }
Session* session = it->second; Session* session = it->second;
// check if dead locked
if (session->tryLock()) {
session->unlock();
session->reset(); session->reset();
session->setActive(false); session->setActive(false);
}
else {
ErrorList errors;
errors.addError(new Error("SessionManager::releaseSession", "found dead locked session, keeping in memory without reference"));
errors.sendErrorsAsEmail();
mRequestSessionMap.erase(requestHandleSession);
return true;
}
// change request handle we don't want session hijacking // change request handle we don't want session hijacking
// hardcoded disabled session max
if (mEmptyRequestStack.size() > 100) {
mRequestSessionMap.erase(requestHandleSession);
delete session;
return true;
}
int newHandle = generateNewUnusedHandle(); int newHandle = generateNewUnusedHandle();
//printf("[SessionManager::releseSession] oldHandle: %ld, newHandle: %ld\n", requestHandleSession, newHandle); //printf("[SessionManager::releseSession] oldHandle: %ld, newHandle: %ld\n", requestHandleSession, newHandle);
// erase after generating new number to prevent to getting the same number again // erase after generating new number to prevent to getting the same number again
@ -349,7 +383,17 @@ void SessionManager::checkTimeoutSession()
//auto timeout = Poco::Timespan(1, 0); //auto timeout = Poco::Timespan(1, 0);
std::stack<int> toRemove; std::stack<int> toRemove;
for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) { for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) {
if (it->second->tryLock()) {
it->second->unlock();
// skip already disabled sessions
if (!it->second->isActive()) continue; if (!it->second->isActive()) continue;
}
else {
// skip dead locked sessions
continue;
}
Poco::Timespan timeElapsed(now - it->second->getLastActivity()); Poco::Timespan timeElapsed(now - it->second->getLastActivity());
if (timeElapsed > timeout) { if (timeElapsed > timeout) {
toRemove.push(it->first); toRemove.push(it->first);

View File

@ -26,5 +26,10 @@ namespace UniLib {
errors.sendErrorsAsEmail(); errors.sendErrorsAsEmail();
} }
} }
bool MultithreadContainer::tryLock()
{
return mWorkMutex.tryLock();
}
} }
} }

View File

@ -43,6 +43,8 @@ namespace UniLib {
public: public:
void lock(const char* stackDetails = nullptr); void lock(const char* stackDetails = nullptr);
// \return false if mutex was locked from another thread
bool tryLock();
inline void unlock() { mLastSucceededLock = ""; mWorkMutex.unlock(); } inline void unlock() { mLastSucceededLock = ""; mWorkMutex.unlock(); }
protected: protected: