mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 17:33:38 +00:00
[java] Fix non-termination when main/2 throws an exception
When main/2 throws an exception we did not properly shutdown the thread pool
and therefore the JVM would not shut down. Simply calling shutdown() in a
finally block is insufficient because then the primordial thread may finish
before the worker thread is able to report the exception thrown by main/2.
This doesn't seem right because the JVM is supposed to wait for all the
non-daemon threads to finish before it exits. I suspect that the primordial
thread is closing stdout and stderr as it exits and therefore the exception
is never seen, but I don't know.
This change fixes the issue by ensuring that shutdown() is always called (in
a finally block) and that the main thread waits for the thread pool to
shutdown before it exits.
java/runtime/MercuryThreadPool.java:
runMain() will not exit until the worker threads have exited.
Create a new method waitForShutdown() that will wait for the thread pool
to shutdown.
Signal the main thread when a worker thread exits.
java/runtime/MercuryWorkerThread.java:
Worker threads now exit if their task raises an unhanded exception.
java/runtime/MercuryRuntime.java:
Allow standalone programs to have the same behavour as programs whose
entrypoint is written in Mercury.
This commit is contained in:
@@ -50,10 +50,15 @@ public class MercuryRuntime
|
||||
* Finalise the runtime system.
|
||||
* This _must_ be called at the normal end of any program. It runs
|
||||
* finalisers and stops the thread pool.
|
||||
* This will wait for the thread pool to shutdown.
|
||||
*/
|
||||
public static void finalise() {
|
||||
MercuryThreadPool pool;
|
||||
|
||||
pool = getThreadPool();
|
||||
JavaInternal.run_finalisers();
|
||||
getThreadPool().shutdown();
|
||||
pool.shutdown();
|
||||
pool.waitForShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user