Menu ▾ ▴

#2072 InterpreterInstance::terminate() calls ActivityManager::dispatchNext() without the dispatch lock

5.3.0
pending
None
none
5
2026-08-09
2026-07-25
No

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.

Related

Bugs: #1650
Bugs: #1736
Bugs: #1849
Bugs: #1937
Bugs: #2020

Discussion

  • Moritz Hoffmann

    Moritz Hoffmann - 2026-08-02
    • status: open --> closed
    • assigned_to: Moritz Hoffmann
     
  • Moritz Hoffmann

    Moritz Hoffmann - 2026-08-02

    Fixed in r13184.

     
  • jfaucher

    jfaucher - 2026-08-09
    • status: closed --> pending
     
  • jfaucher

    jfaucher - 2026-08-09

    Commit [r13184]

     

    Related

    Commit: [r13184]

Anonymous
Anonymous

Add attachments
Cancel