Skip to content

Commit 12c0206

Browse files
authored
Merge pull request #3 from Unity-Technologies/soft-shutdown-review-comments-2
Soft shutdown review comments 2
2 parents e38a363 + 80a7644 commit 12c0206

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

src/runtime/runtime.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ internal static Version PyVersion
127127
/// <summary>
128128
/// Initialize the runtime...
129129
/// </summary>
130-
/// <remarks>When calling this method after a soft shutdown or a domain reload,
131-
/// this method acquires and releases the GIL. </remarks>
130+
/// <remarks>Always call this method from the Main thread. After the
131+
/// first call to this method, the main thread has acquired the GIL.</remarks>
132132
internal static void Initialize(bool initSigs = false, ShutdownMode mode = ShutdownMode.Default, bool fromPython = false)
133133
{
134134
if (_isInitialized)
@@ -407,15 +407,21 @@ internal static void Shutdown(ShutdownMode mode)
407407
GC.Collect();
408408
try
409409
{
410-
GC.WaitForFullGCComplete();
410+
GC.WaitForPendingFinalizers();
411411
}
412412
catch (NotImplementedException)
413413
{
414414
// Some clr runtime didn't implement GC.WaitForFullGCComplete yet.
415415
}
416416
PyGILState_Release(state);
417-
// Then release the GIL for good.
418-
PyEval_SaveThread();
417+
// Then release the GIL for good, if there is somehting to release
418+
// Use the unchecked version as the checked version calls `abort()`
419+
// if the current state is NULL.
420+
if (_PyThreadState_UncheckedGet() != IntPtr.Zero)
421+
{
422+
PyEval_SaveThread();
423+
}
424+
419425
}
420426
else
421427
{
@@ -846,6 +852,9 @@ internal static unsafe long Refcount(IntPtr op)
846852
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
847853
internal static extern IntPtr PyThreadState_Get();
848854

855+
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
856+
internal static extern IntPtr _PyThreadState_UncheckedGet();
857+
849858
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
850859
internal static extern IntPtr PyThread_get_key_value(IntPtr key);
851860

src/runtime/runtime_data.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,19 @@ public static void ClearStash()
137137
PySys_SetObject("clr_data", IntPtr.Zero);
138138
}
139139

140+
static bool CheckSerializable (object o)
141+
{
142+
Type type = o.GetType();
143+
do
144+
{
145+
if (!type.IsSerializable)
146+
{
147+
return false;
148+
}
149+
} while ((type = type.BaseType) != null);
150+
return true;
151+
}
152+
140153
private static void SaveRuntimeDataObjects(RuntimeDataStorage storage)
141154
{
142155
var objs = ManagedType.GetManagedObjects();
@@ -151,7 +164,7 @@ private static void SaveRuntimeDataObjects(RuntimeDataStorage storage)
151164
switch (entry.Value)
152165
{
153166
case ManagedType.TrackTypes.Extension:
154-
Debug.Assert(obj.GetType().IsSerializable);
167+
Debug.Assert(CheckSerializable(obj));
155168
var context = new InterDomainContext();
156169
contexts[obj.pyHandle] = context;
157170
obj.Save(context);
@@ -195,7 +208,7 @@ private static void SaveRuntimeDataObjects(RuntimeDataStorage storage)
195208
{
196209
if (!item.Stored)
197210
{
198-
if (!item.Instance.GetType().IsSerializable)
211+
if (!CheckSerializable(item.Instance))
199212
{
200213
continue;
201214
}

0 commit comments

Comments
 (0)