JRE-373 [macos] nativeCreateNSWindow deadlocks with a11y
diff --git a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
index e879070..afa8c20 100644
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
@@ -35,6 +35,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.Callable;
 
 import javax.swing.*;
 
@@ -249,8 +250,10 @@
         } else {
             bounds = _peer.constrainBounds(_target.getBounds());
         }
-        final long nativeWindowPtr = nativeCreateNSWindow(contentView.getAWTView(),
-                ownerPtr, styleBits, bounds.x, bounds.y, bounds.width, bounds.height);
+        long nativeWindowPtr = LWCToolkit.performOnMainThreadWaiting(() ->
+                nativeCreateNSWindow(contentView.getAWTView(),
+                                     ownerPtr, styleBits,
+                                     bounds.x, bounds.y, bounds.width, bounds.height));
         setPtr(nativeWindowPtr);
 
         if (target instanceof javax.swing.RootPaneContainer) {
diff --git a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
index 654fbc3..36d97cf 100644
--- a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
+++ b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
@@ -39,7 +39,7 @@
 import java.net.URL;
 import java.security.*;
 import java.util.*;
-import java.util.concurrent.Callable;
+import java.util.concurrent.*;
 import java.net.MalformedURLException;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -634,6 +634,51 @@
         }
     }
 
+    private static ExecutorService onMainThreadExecutor;
+
+    /**
+     * Performs the callable on the main thread running a secondary loop on EDT while waiting for the result.
+     * <p>
+     * The callable should delegate to the native method which is expected to execute
+     * [JNFRunLoop performOnMainThreadWaiting:YES ...]. Note that the native doAWTRunLoop runs in
+     * [JNFRunLoop javaRunLoopMode] which accepts selectors of the kind. The callable should not execute
+     * any Java code which would normally be executed on EDT.
+     * <p>
+     * The method must be called on EDT. It's reentrant.
+     */
+    public static <T> T performOnMainThreadWaiting(Callable<T> callable) {
+        if (!EventQueue.isDispatchThread()) {
+            throw new RuntimeException("the method must be called on the Event Dispatching thread");
+        }
+        if (callable == null) return null;
+
+        if (onMainThreadExecutor == null) {
+            // init on EDT
+            onMainThreadExecutor = new ThreadPoolExecutor(1, Integer.MAX_VALUE,
+                    60L, TimeUnit.SECONDS,
+                    new SynchronousQueue<>(),
+                    Executors.privilegedThreadFactory());
+
+        }
+        Future<T> task = onMainThreadExecutor.submit(() -> {
+            T res =  callable.call();
+            EventQueue.invokeLater(() -> {/* wake up EDT */});
+            return res;
+        });
+
+        AWTAccessor.getEventQueueAccessor().createSecondaryLoop(
+            Toolkit.getDefaultToolkit().getSystemEventQueue(),
+            () -> !task.isDone()).enter();
+
+        try {
+            return task.get();
+        } catch (InterruptedException | ExecutionException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
     /**
      * Kicks an event over to the appropriate event queue and waits for it to
      * finish To avoid deadlocking, we manually run the NSRunLoop while waiting