-
Notifications
You must be signed in to change notification settings - Fork 398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deadlock in shared mem mutex when apps are killed #325
Comments
…case application fails to unlock mutex and terminate Signed-off-by: Sumedha Maharudrayya Mathad (RBEI/ESU4) <[email protected]>
Signed-off-by: Hintz Martin (CC-AD/ESW1) <[email protected]>
Signed-off-by: Hintz Martin (CC-AD/ESW1) <[email protected]>
Signed-off-by: Hintz Martin (CC-AD/ESW1) <[email protected]>
…case application fails to unlock mutex and terminate Signed-off-by: Sumedha Maharudrayya Mathad (RBEI/ESU4) <[email protected]>
Signed-off-by: Hintz Martin (CC-AD/ESW1) <[email protected]>
Signed-off-by: Hintz Martin (CC-AD/ESW1) <[email protected]>
Signed-off-by: Hintz Martin (CC-AD/ESW1) <[email protected]>
I've had an idea how this could be solved in an elegant way without a mutex but an atomic and semaphore instead. class DualAccessTransactionTray
{
private:
class AccessGuard;
public:
AccessGuard acquireRouDiAccess()
{
switch (m_accessToken.exchange(AccessToken::ROUDI, std::memory_order_acquire))
{
case AccessToken::NONE:
break;
case AccessToken::ROUDI:
errorHandler(kBROKEN_INVARIANT);
break;
case AccessToken::APP:
m_waitingLine.wait();
break;
}
return AccessGuard{*this, AccessToken::ROUDI};
}
AccessGuard acquireAppAccess()
{
switch (m_accessToken.exchange(AccessToken::APP, std::memory_order_acquire))
{
case AccessToken::NONE:
break;
case AccessToken::ROUDI:
m_waitingLine.wait();
break;
case AccessToken::APP:
errorHandler(kBROKEN_INVARIANT);
break;
}
return AccessGuard{*this, AccessToken::APP};
}
void cleanupAfterAppWalkedThePlank()
{
releaseAccess(AccessToken::APP);
// just to be sure the memory is synchronized
AccessToken expected = AccessToken::APP;
m_accessToken.compare_exchange_strong(expected, AccessToken::NONE, std::memory_order_acq_rel);
}
private:
enum class AccessToken
{
NONE,
ROUDI,
APP
};
void releaseAccess(AccessToken expected)
{
auto casSuccessful =
m_accessToken.compare_exchange_strong(expected, AccessToken::NONE, std::memory_order_release);
if (!casSuccessful)
{
if (expected == AccessToken::NONE)
{
errorHandler(kBROKEN_INVARIANT);
}
m_waitingLine.post();
}
}
class AccessGuard
{
public:
AccessGuard(DualAccessTransactionTray& transactionTray, AccessToken accessToken)
: m_transactionTray(transactionTray)
, m_accessToken(accessToken)
{
}
~AccessGuard()
{
m_transactionTray.releaseAccess(m_accessToken);
}
private:
DualAccessTransactionTray& m_transactionTray;
AccessToken m_accessToken{AccessToken::NONE};
};
std::atomic<AccessToken> m_accessToken{AccessToken::NONE};
posix::Semaphore m_waitingLine;
}; So basically a futex but just for two threads. If the application terminates abnormally, the semaphore can be cleaned up contrary to the mutex which cannot be unlocked from an other thread than the one which acquired the lock. This would be an example of a concurrent access from RouDi and the application
@budrus @MatthiasKillat @elfenpiff what do you think? |
@elBoberido so like a mutex that can be unlocked by someone else if this one is sure that the locking one walked the plank. But we could still have corrupted data structures which we maybe are not allowed to access. So we could detect and continue with the consequence that chunks are lost. Or we have to go for the extended UsedChunkList to have a more robust data structure. |
@budrus yes, the history vector might be corrupted. The simple approach would indeed be to leak chunks and print a warning if RouDi detects that the lock was hold by the application. A more sophisticated solution would be a |
Signed-off-by: Mathias Kraus <[email protected]>
Signed-off-by: Mathias Kraus <[email protected]>
Signed-off-by: Mathias Kraus <[email protected]>
@marthtz @sculpordwarf @bishibashiB @shankar-in cc @CarolinaGGB |
@mossmaurice @marthtz is on vacation. he will be back in 2 weeks. |
Required information
Operating system:
Ubuntu 18.04 LTS
Compiler version:
GCC 7.4.0
Observed result or behaviour:
Deadlock in shared mem mutex when apps are killed
Expected result or behaviour:
No deadlock.
Conditions where it occurred / Performed steps:
Kill an app while some system is running
Related issues
The text was updated successfully, but these errors were encountered: