From fea43ce0c424fcb1e119e18be0bb72fe38f18b12 Mon Sep 17 00:00:00 2001 From: Bhekanani Cele Date: Tue, 23 Jun 2026 11:52:36 +0200 Subject: [PATCH] Fix deadlock between auto-pause and action execution The lock-splitting change (splitting _lock into _actionsLock and _pauseLock) introduced a lock-ordering deadlock when AutoPause is enabled. _autoPauseTimer_Elapsed held _pauseLock and called Stop() which acquires _actionsLock, while PerformActions held _actionsLock and called StopAutoPauseTimer() which acquires _pauseLock. Move the Stop() call outside the _pauseLock in _autoPauseTimer_Elapsed to break the circular dependency. --- Move Mouse/ViewModels/MouseWindowViewModel.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Move Mouse/ViewModels/MouseWindowViewModel.cs b/Move Mouse/ViewModels/MouseWindowViewModel.cs index 6ed212e..6881388 100644 --- a/Move Mouse/ViewModels/MouseWindowViewModel.cs +++ b/Move Mouse/ViewModels/MouseWindowViewModel.cs @@ -795,7 +795,7 @@ private void StartAutoPauseTimer() private void StopAutoPauseTimer() { StaticCode.Logger?.Here().Debug(String.Empty); - + lock (_pauseLock) { try @@ -814,14 +814,22 @@ private void _autoPauseTimer_Elapsed(object sender, System.Timers.ElapsedEventAr try { StaticCode.Logger?.Here().Debug(StaticCode.GetLastInputTime().ToString()); + bool shouldStop = false; + MouseState stopState = MouseState.Idle; lock (_pauseLock) { if (CurrentState.Equals(MouseState.Running) && (StaticCode.GetLastInputTime() < TimeSpan.FromMilliseconds(_autoPauseTimer.Interval))) { - Stop((SettingsVm.Settings.AutoPause && SettingsVm.Settings.AutoResume) ? MouseState.Paused : MouseState.Idle); + shouldStop = true; + stopState = (SettingsVm.Settings.AutoPause && SettingsVm.Settings.AutoResume) ? MouseState.Paused : MouseState.Idle; } } + + if (shouldStop) + { + Stop(stopState); + } } catch (Exception ex) { @@ -1102,4 +1110,4 @@ public void Dispose() } } } -} \ No newline at end of file +}