diff --git a/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java b/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java index cf23a4034b..059817587d 100644 --- a/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java +++ b/graalpython/com.oracle.graal.python.shell/src/com/oracle/graal/python/shell/GraalPythonMain.java @@ -874,6 +874,16 @@ protected void launch(Builder contextBuilder) { } catch (IOException e) { rc = 1; e.printStackTrace(); + } catch (Throwable t) { + // On some paths (e.g. Windows, issue #543) the polyglot-threads error may be wrapped + // or reported differently; catch so we never exit without handling and produce a silent crash. + if (t.getMessage() != null && t.getMessage().contains("did not complete all polyglot threads")) { + if (!verboseFlag) { + System.exit(rc); + } + } else { + throw t; + } } System.exit(rc); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java index 664704efba..788d0840f8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java @@ -45,6 +45,7 @@ import java.util.EnumSet; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; @@ -1090,7 +1091,12 @@ protected void initializeThread(PythonContext context, Thread thread) { } @Override + @TruffleBoundary protected void disposeThread(PythonContext context, Thread thread) { + // On Windows, yield to allow other threads to progress during shutdown (issue #543). + if (System.getProperty("os.name", "").toLowerCase(Locale.ROOT).contains("win")) { + Thread.yield(); + } context.disposeThread(thread, false); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java index 1b91e7d4d7..9297c196ab 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java @@ -84,6 +84,7 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import java.util.WeakHashMap; @@ -213,6 +214,9 @@ public final class PythonContext extends Python3Core { private static final TruffleLogger LOGGER = PythonLanguage.getLogger(PythonContext.class); + /** On Windows, use longer join timeouts to reduce "did not complete all polyglot threads" (issue #543). */ + private static final boolean IS_WINDOWS = System.getProperty("os.name", "").toLowerCase(Locale.ROOT).contains("win"); + public final HandleContext nativeContext = new HandleContext(DEBUG_CAPI); public final NativeBufferContext nativeBufferContext = new NativeBufferContext(); public final ArrowSupport arrowSupport = new ArrowSupport(this); @@ -2174,8 +2178,8 @@ private void joinPythonThreads() { disposeThread(thread, true); boolean isOurThread = runViaLauncher || thread.getThreadGroup() == threadGroup; // Do not try so hard when running in embedded mode and the thread may not be - // running any GraalPython code anymore - int tries = isOurThread ? 100 : 5; + // running any GraalPython code anymore. On Windows use more attempts (issue #543). + int tries = isOurThread ? (IS_WINDOWS ? 200 : 100) : 5; for (int i = 0; i < tries && thread.isAlive(); i++) { thread.join(tries - i); if (!thread.isAlive()) { @@ -2227,7 +2231,7 @@ private void joinSystemThreads() { } assert thread != Thread.currentThread(); LOGGER.finest("joining thread " + thread); - int tries = 100; + int tries = IS_WINDOWS ? 200 : 100; for (int i = 0; i < tries && thread.isAlive(); i++) { killSystemThread(thread); try {