Skip to content

Park Darwin main thread in CFRunLoop for headed AWT/Swing to fix hang#13996

Open
The-Alchemist wants to merge 1 commit into
oracle:masterfrom
The-Alchemist:darwin-park-main-cfrunloop
Open

Park Darwin main thread in CFRunLoop for headed AWT/Swing to fix hang#13996
The-Alchemist wants to merge 1 commit into
oracle:masterfrom
The-Alchemist:darwin-park-main-cfrunloop

Conversation

@The-Alchemist

@The-Alchemist The-Alchemist commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Exploratory fix for Darwin headed AWT/Swing hang (#13994; related #4124).

After AWT dylibs/shims (#13282), native-image Swing still deadlocks because pthread main never enters an AppKit/CFRunLoop while Metal/CGL uses performSelector:…waitUntilDone. HotSpot/libjli and Graal sdk/.../launcher.cc already park the process main thread; SubstrateVM JavaMainWrapper did not.

This PR adds experimental -H:+DarwinParkMainInCFRunLoop that:

  1. Runs Java main on a dedicated platform thread (existing runMainRoutine machinery).
  2. Parks the process main thread in CFRunLoopRunInMode (libjli / ParkEventLoop pattern).
  3. After runCore, waits for non-daemon threads + isolate shutdown on the side thread, then LibC.exit (matches Darwin launcher.cc).

Test plan

  • mx build substratevm
  • native-image -H:+UnlockExperimentalVMOptions -H:+DarwinParkMainInCFRunLoop -H:Preserve=module=java.desktop … MinimalSwing
  • Minimal SwingUtilities.invokeLater + JFrame writes a ready marker (window path progresses; previously hung before UI)
  • Maintainer review of gating (default-on for AWT images vs expert flag) and shutdown/System.exit interaction
  • Consider Darwin headed smoke test (today NonHeadlessJavaDesktopTest is Linux-only)

Specifications

  • Mac OS X 26.5.2 (25F84)
  • MacBook Pro with Apple M4 Max

Notes for reviewers

  • Draft / not merge-ready: wants guidance on default-on gating when AWT is registered, and on LibC.exit vs cancelable CFRunLoopStop + re-attach shutdown on the initial thread.
  • Reference implementation: sdk/src/org.graalvm.launcher.native/src/launcher.cc (ParkEventLoop) and OpenJDK libjli/java_md_macosx.m.

Without libjli-equivalent CFRunLoop parking, SubstrateVM leaves pthread main
in ThreadsLock.wait while Metal/CGL performSelector:waitUntilDone deadlocks
(oracle#13994). Mirror OpenJDK libjli / Graal launcher ParkEventLoop behind
-H:+DarwinParkMainInCFRunLoop (default off).

Signed-off-by: The-Alchemist <karl@digital-alchemy.io>
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Jul 16, 2026
@The-Alchemist The-Alchemist changed the title Park Darwin main thread in CFRunLoop for headed AWT/Swing Park Darwin main thread in CFRunLoop for headed AWT/Swing to avoid hang Jul 16, 2026
@The-Alchemist The-Alchemist changed the title Park Darwin main thread in CFRunLoop for headed AWT/Swing to avoid hang Park Darwin main thread in CFRunLoop for headed AWT/Swing to fix hang Jul 16, 2026
@The-Alchemist
The-Alchemist marked this pull request as ready for review July 16, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant