mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
adding safe guard for skipping dead locked sessions
This commit is contained in:
parent
f849abc386
commit
c9ee1d9178
@ -147,16 +147,30 @@ 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;
|
||||||
result->reset();
|
// check if dead locked
|
||||||
//mWorkingMutex.unlock();
|
if (result->tryLock()) {
|
||||||
|
result->unlock();
|
||||||
|
if (!result->isActive()) {
|
||||||
|
result->reset();
|
||||||
|
//mWorkingMutex.unlock();
|
||||||
|
|
||||||
if (handle) {
|
if (handle) {
|
||||||
*handle = local_handle;
|
*handle = local_handle;
|
||||||
|
}
|
||||||
|
result->setActive(true);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result->setActive(true);
|
else {
|
||||||
return result;
|
ErrorList errors;
|
||||||
|
errors.addError(new Error("SessionManager::getNewSession", "found dead locked session, keeping in memory without reference"));
|
||||||
|
errors.sendErrorsAsEmail();
|
||||||
|
|
||||||
|
mRequestSessionMap.erase(local_handle);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,10 +221,30 @@ bool SessionManager::releaseSession(int requestHandleSession)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Session* session = it->second;
|
Session* session = it->second;
|
||||||
session->reset();
|
// check if dead locked
|
||||||
session->setActive(false);
|
if (session->tryLock()) {
|
||||||
|
session->unlock();
|
||||||
|
session->reset();
|
||||||
|
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->isActive()) continue;
|
|
||||||
|
if (it->second->tryLock()) {
|
||||||
|
it->second->unlock();
|
||||||
|
// skip already disabled sessions
|
||||||
|
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);
|
||||||
|
|||||||
@ -26,5 +26,10 @@ namespace UniLib {
|
|||||||
errors.sendErrorsAsEmail();
|
errors.sendErrorsAsEmail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MultithreadContainer::tryLock()
|
||||||
|
{
|
||||||
|
return mWorkMutex.tryLock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user