Skip to content

Fix silent startup deadlock on Windows 11 due to premature FreeLibrary - #1155

Merged
sabrogden merged 2 commits into
sabrogden:masterfrom
int03:fix/power-manager-startup-deadlock
Sep 22, 2026
Merged

sabrogden merged 2 commits into
sabrogden:masterfrom
int03:fix/power-manager-startup-deadlock

Conversation

@int03

@int03 int03 commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

In CPowerManager::Start, powrprof.dll was loaded, PowerRegisterSuspendResumeNotification was called, and ::FreeLibrary(powrprof) was immediately invoked.

On modern Windows 11 builds, calling FreeLibrary on powrprof.dll while a suspend/resume notification callback is active causes powrprof to invoke UMPDC.dll, which executes WaitForSingleObjectEx during DLL unload under the loader lock, deadlocking the main UI thread synchronously during CMainFrame::OnCreate. As a result, Ditto hangs permanently on startup without creating its systray icon or showing any windows.

In addition, PowerUnregisterSuspendResumeNotification takes HPOWERNOTIFY by value, not by pointer.

This fix:

  1. Retains HMODULE m_hPowrProf as a member of CPowerManager across the application lifetime.
  2. Keeps powrprof.dll loaded while notifications are registered.
  3. Corrects the function signature and invocation for PowerUnregisterSuspendResumeNotification.
  4. Safely unregisters notifications and frees powrprof.dll only during CPowerManager::Close().

Windows 11 Pro for Workstations Insider Preview
Dev 29634.1000

In CPowerManager::Start, powrprof.dll was loaded, PowerRegisterSuspendResumeNotification
was called, and ::FreeLibrary(powrprof) was immediately invoked.

On modern Windows 11 builds, calling FreeLibrary on powrprof.dll while a suspend/resume
notification callback is active causes powrprof to invoke UMPDC.dll, which executes
WaitForSingleObjectEx during DLL unload under the loader lock, deadlocking the main UI thread
synchronously during CMainFrame::OnCreate. As a result, Ditto hangs permanently on startup
without creating its systray icon or showing any windows.

In addition, PowerUnregisterSuspendResumeNotification takes HPOWERNOTIFY by value, not by
pointer.

This fix:
1. Retains HMODULE m_hPowrProf as a member of CPowerManager across the application lifetime.
2. Keeps powrprof.dll loaded while notifications are registered.
3. Corrects the function signature and invocation for PowerUnregisterSuspendResumeNotification.
4. Safely unregisters notifications and frees powrprof.dll only during CPowerManager::Close().
Copilot AI lite review requested due to automatic review settings September 22, 2026 10:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unregister failures are ignored, allowing the module to be unloaded while notifications may remain registered.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

Fixes a Windows startup deadlock by retaining powrprof.dll while power notifications are registered and correcting notification cleanup.

Changes:

  • Retains the DLL handle across the manager lifecycle.
  • Corrects notification unregistration usage.
  • Defers unregistering and unloading until shutdown.
File Description
src/​PowerManager.h Adds persistent power-management DLL state and updates cleanup declarations.
src/​PowerManager.cpp Updates DLL loading, notification registration, unregistration, and cleanup.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/PowerManager.cpp Outdated
Comment on lines +75 to +80
PowerUnregisterSuspendResumeNotification(m_registrationHandle);
}

::FreeLibrary(powrprof);
m_registrationHandle = 0;
}

::FreeLibrary(m_hPowrProf);
@sabrogden
sabrogden merged commit cea4b24 into sabrogden:master Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants