-
Couldn't load subscription status.
- Fork 27
Description
When a solver instance is cancelled due to a timeout, control-C, SIGTERM, etc., the Python driver cancels the solver instance by calling proc.terminate(). On Linux, it sends SIGTERM to the child process, which does a graceful shutdown of the minizinc app as expected.
Windows does not support SIGTERM. Instead, proc.terminate() nukes the child process by calling the Win32 API TerminateProcess on it, which is equivalent to kill -9 SIGKILL. It results in a very abrupt termination of the minizinc app. This in turn can fail to stop the underlying solver child subprocess.
On Windows, the minizinc app listens for a CTRL_C_EVENT in lieu of SIGTERM. The fix is to send CTRL_C_EVENT via proc.send_signal() instead of nuking the process via proc.terminate():
--- a/src/minizinc/instance.py
+++ b/src/minizinc/instance.py
@@ -452,7 +452,11 @@ class Instance(Model):
# Process was cancelled by the user, a MiniZincError occurred, or
# an unexpected Python exception occurred
# First, terminate the process
- proc.terminate()
+ if sys.platform == "win32":
+ import signal
+ proc.send_signal(signal.CTRL_C_EVENT)
+ else:
+ proc.terminate()
_ = await proc.wait()
# Then, reraise the error that occurred
raiseFor additional information, see the Python documentation for proc.terminate() and proc.send_signal()
Note that minizinc-python sets the CREATE_NEW_CONSOLE flag in the creationflags parameter to create the isolated child process group, so CTRL_C_EVENT works as expected.