You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix mino_pcall re-throw via set_eval_diag (STM lock leak)
mino_pcall's catch arm called set_eval_diag to publish the caught
error's message via mino_last_error. But set_eval_diag itself
longjmps to the next-outer try frame when one exists -- so any
pcall caller that ran inside a Clojure try would see its catch
path hijacked by the longjmp and unwind to the outer frame,
leaking any bookkeeping the caller depended on.
In the STM commit path, that bookkeeping was the global commit
lock: a validator throw inside a (try (dosync ...) (catch ...))
would longjmp out of run_ref_validator past stm_unlock, leaving
S->stm_commit_lock permanently held. The next dosync deadlocked.
Extract a non-throwing variant record_eval_diag from set_eval_diag
and route mino_pcall's catch arm through it. The throw-conversion
path of set_eval_diag is preserved for its primary use case
(turning eval-phase diagnostics into catchable exceptions).
Adds tests/stm_test.clj validator-throw-does-not-deadlock-stm-lock:
the first tx errors via retry exhaustion; the second tx completes
instead of hanging.
The agent code's agent_try_call (added in E.4 as a workaround) is
left in place; a follow-up commit can fold it back into mino_pcall
if preferred.
Internal suite 1513 / 7169 / 0. External baseline unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments