From 29b73c5d603389bf26860ab94fe855651b8929e9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 May 2026 18:15:03 +0000 Subject: [PATCH 1/2] Initial plan From cb47a4a74b3e9dee494421cabb0cb5d6cdc53b79 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 May 2026 18:21:04 +0000 Subject: [PATCH 2/2] fix: resolve deadlock in beginJob when compiled debug The deadlock was caused by two issues: 1. Lock ordering: beginJob() held m_ while creating XThreadTimer (which acquires gSystemMutex internally), while the app thread could hold gSystemMutex (inside ProcessEvents) and try to acquire m_ via a timer callback - classic ABBA deadlock. 2. Bare cv_.wait() without predicate: susceptible to missed notifications if the signal was sent before the wait began. Fix: - Add appStarted_ and eveSetupDone_ boolean state flags - Use predicate-based cv_.wait() to handle missed notifications - Don't hold m_ during XThreadTimer creation to avoid lock ordering issue --- src/Mu2eEventDisplay_module.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Mu2eEventDisplay_module.cc b/src/Mu2eEventDisplay_module.cc index be59bd8..b9d3b5e 100644 --- a/src/Mu2eEventDisplay_module.cc +++ b/src/Mu2eEventDisplay_module.cc @@ -164,6 +164,8 @@ namespace mu2e // Control between the main thread and event-display thread std::condition_variable cv_{}; std::mutex m_{}; + bool appStarted_{false}; + bool eveSetupDone_{false}; int diagLevel_; bool showCrv_; @@ -255,22 +257,28 @@ namespace mu2e void Mu2eEventDisplay::signalAppStart() { std::unique_lock lock{m_}; + appStarted_ = true; cv_.notify_all(); } void Mu2eEventDisplay::beginJob(){ if(diagLevel_ == 1) std::cout<<"[Mu2eEventDisplay : beginJob()] -- starting ..."<GetElementId() << std::endl; }