Skip to content

Fix macOS broker deadlock by processing CFRunLoop in MacMainThreadScheduler#5966

Open
embetten wants to merge 3 commits intoAzureAD:mainfrom
embetten:users/embetten/macos-broker-deadlock-fix
Open

Fix macOS broker deadlock by processing CFRunLoop in MacMainThreadScheduler#5966
embetten wants to merge 3 commits intoAzureAD:mainfrom
embetten:users/embetten/macos-broker-deadlock-fix

Conversation

@embetten
Copy link
Copy Markdown

On macOS, MacMainThreadScheduler.StartMessageLoop() uses Thread.Sleep to wait between processing queued actions. However, the native MSAL broker runtime may use dispatch_sync to the main GCD queue (e.g. during FallbackToNativeMsal on devices without an SSO extension). Because Thread.Sleep does not service the GCD queue, dispatch_sync blocks forever waiting for the main thread — resulting in a deadlock.

This PR replaces Thread.Sleep with CFRunLoopRunInMode on macOS, which processes pending GCD dispatch calls while waiting. On non-macOS platforms, the existing Thread.Sleep behavior is preserved.

Fixes #
#5940

Changes proposed in this request

  • Add CoreFoundationInterop nested class with P/Invoke bindings to macOS CoreFoundation (CFRunLoopRunInMode, CFStringCreateWithCString)
  • In StartMessageLoop, call CoreFoundationInterop.ProcessRunLoop() instead of Thread.Sleep when running on macOS
  • P/Invoke bindings are isolated in a nested class so the DllImport is only JIT-resolved on macOS

Testing

  • Manually tested on a macOS ARM64 device using Azure Artifacts credential providers with the MSAL broker. Confirmed the deadlock no longer occurs during FallbackToNativeMsal on a non-Intune macOS device without the SSO extension.
  • Confirmed broker still works with SSO enabled on a macOS ARM64.
  • Manually tested WAM on a windows machine.

Performance impact
CFRunLoopRunInMode with the same sleep interval behaves equivalently to Thread.Sleep for timing purposes, while additionally servicing the run loop. No measurable performance difference expected.

Documentation
I am not aware of any related documentation

…eduler

On macOS, the native MSAL broker runtime may use dispatch_sync to the main GCD queue (e.g. during FallbackToNativeMsal on devices without an SSO extension). The existing Thread.Sleep in the message loop prevents the main thread from servicing the GCD queue, causing a deadlock.

Replace Thread.Sleep with CFRunLoopRunInMode on macOS so dispatch_sync calls targeting the main queue can execute while the scheduler waits for new work.
Copilot AI review requested due to automatic review settings April 30, 2026 23:08
@embetten embetten requested a review from a team as a code owner April 30, 2026 23:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Fixes a macOS deadlock in MacMainThreadScheduler.StartMessageLoop() by pumping the CoreFoundation run loop (servicing GCD main-queue dispatch_sync) instead of using Thread.Sleep when running on macOS.

Changes:

  • Added macOS CoreFoundation P/Invoke bindings in a nested CoreFoundationInterop class.
  • Replaced Thread.Sleep with CFRunLoopRunInMode on macOS while preserving Thread.Sleep elsewhere.

Comment on lines +63 to +73
private static IntPtr s_defaultMode;

private static IntPtr GetDefaultMode()
{
if (s_defaultMode == IntPtr.Zero)
{
s_defaultMode = CFStringCreateWithCString(
IntPtr.Zero, "kCFRunLoopDefaultMode", KCFStringEncodingUTF8);
}

return s_defaultMode;
Comment thread src/client/Microsoft.Identity.Client/Utils/MacMainThreadScheduler.cs Outdated
@embetten
Copy link
Copy Markdown
Author

@copilot apply changes based on the comments in this thread

@gladjohn gladjohn requested review from ashok672 and fengga May 1, 2026 02:57
@gladjohn
Copy link
Copy Markdown
Contributor

gladjohn commented May 1, 2026

@ashok672 @fengga can you review this please

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