Skip to content

Commit 914ff18

Browse files
committed
handle ProcessExit event to avoid Python crash when CLR (in particular Mono) is unloaded before Python stops
1 parent 21169db commit 914ff18

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

src/runtime/pythonengine.cs

+7
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ public static void Initialize(IEnumerable<string> args, bool setSysArgv = true,
192192

193193
// Make sure we clean up properly on app domain unload.
194194
AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;
195+
AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
195196

196197
// The global scope gets used implicitly quite early on, remember
197198
// to clear it out when we shut down.
@@ -249,6 +250,11 @@ static void OnDomainUnload(object _, EventArgs __)
249250
Shutdown();
250251
}
251252

253+
static void OnProcessExit(object _, EventArgs __)
254+
{
255+
Shutdown();
256+
}
257+
252258
/// <summary>
253259
/// A helper to perform initialization from the context of an active
254260
/// CPython interpreter process - this bootstraps the managed runtime
@@ -319,6 +325,7 @@ public static void Shutdown(ShutdownMode mode)
319325
// If the shutdown handlers trigger a domain unload,
320326
// don't call shutdown again.
321327
AppDomain.CurrentDomain.DomainUnload -= OnDomainUnload;
328+
AppDomain.CurrentDomain.ProcessExit -= OnProcessExit;
322329

323330
PyScopeManager.Global.Clear();
324331
ExecuteShutdownHandlers();

src/runtime/runtime.cs

+4
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ internal static void Shutdown(ShutdownMode mode)
393393
{
394394
Py_Finalize();
395395
}
396+
else
397+
{
398+
PyGILState_Release(state);
399+
}
396400
}
397401
}
398402

0 commit comments

Comments
 (0)