Three of the four dispatchNext() call sites hold the dispatch lock; one does not.
interpreter/concurrency/ActivityManager.cpp:310 addWaitingActivity - DispatchSection held
interpreter/concurrency/ActivityManager.cpp:755 releaseAccess - DispatchSection held
interpreter/concurrency/ActivityManager.cpp:1059 suspendDispatch - DispatchSection held
interpreter/runtime/InterpreterInstance.cpp:569 terminate - NO dispatch lock
if (activityCreated)
ActivityManager::releaseAccess(); // takes DispatchSection internally
else
ActivityManager::dispatchNext(); // walks and pops waitingActivities unlocked
The only ResourceSection in terminate() is a different lock in a scope that has already closed.
dispatchNext() iterates and pops waitingActivities, so this violates the contract that
removeWaitingActivity() documents explicitly: "NOTE: The caller must be holding the dispatch lock".
One safe fix is to have dispatchNext() acquire DispatchSection itself — the dispatch mutex is
recursive (SysSemaphore.cpp:359 sets PTHREAD_MUTEX_RECURSIVE), so the three existing callers are
unaffected. I tested that change over 5 full test-suite runs with no deadlock.
Note it did not fix the crash in [bugs:#2020] on its own, which is consistent with the silent
lock failure described in the companion ticket — taking a destroyed mutex is a no-op.
Bugs: #1650
Bugs: #1736
Bugs: #1849
Bugs: #1937
Bugs: #2020
Anonymous
Fixed in r13184.
Commit [r13184]
Related
Commit: [r13184]