8000 * Use environment variable `PYTHONNET_SOFT_SHUTDOWN` to enable soft s… · pythonnet/pythonnet@cc9e7e5 · GitHub
[go: up one dir, main page]

Skip to content

Commit cc9e7e5

Browse files
committed
* Use environment variable PYTHONNET_SOFT_SHUTDOWN to enable soft shutdown forcedly
* Disable restore objects on default
1 parent d108913 commit cc9e7e5

File tree

6 files changed

+53
-23
lines changed

6 files changed

+53
-23
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ env:
1111
matrix:
1212
- BUILD_OPTS=--xplat NUNIT_PATH="~/.nuget/packages/nunit.consolerunner/3.*/tools/nunit3-console.exe" RUN_TESTS=dotnet EMBED_TESTS_PATH=netcoreapp2.0_publish/
1313
- BUILD_OPTS="" NUNIT_PATH="./packages/NUnit.*/tools/nunit3-console.exe" RUN_TESTS="mono $NUNIT_PATH" EMBED_TESTS_PATH=""
14+
- PYTHONNET_SOFT_SHUTDOWN="1" BUILD_OPTS=--xplat NUNIT_PATH="~/.nuget/packages/nunit.consolerunner/3.*/tools/nunit3-console.exe" RUN_TESTS=dotnet EMBED_TESTS_PATH=netcoreapp2.0_publish/
15+
- PYTHONNET_SOFT_SHUTDOWN="1" BUILD_OPTS="" NUNIT_PATH="./packages/NUnit.*/tools/nunit3-console.exe" RUN_TESTS="mono $NUNIT_PATH" EMBED_TESTS_PATH=""
1416

1517
global:
1618
- LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so

appveyor.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ build: off
33

44
image:
55
- Visual Studio 2017
6-
6+
77
platform:
88
- x86
99
- x64
@@ -15,7 +15,7 @@ environment:
1515
CODECOV_ENV: PYTHON_VERSION, PLATFORM
1616

1717
matrix:
18-
- PYTHON_VERSION: 2.7
18+
- PYTHON_VERSION: 2.7
1919
BUILD_OPTS: --xplat
2020
- PYTHON_VERSION: 3.5
2121
BUILD_OPTS: --xplat
@@ -28,6 +28,9 @@ environment:
2828
- PYTHON_VERSION: 3.6
2929
- PYTHON_VERSION: 3.7
3030

31+
- PYTHON_VERSION: 3.7
32+
PYTHONNET_SOFT_SHUTDOWN: 1
33+
3134
matrix:
3235
allow_failures:
3336
- PYTHON_VERSION: 3.4

src/runtime/pythonengine.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Python.Runtime
1212
/// </summary>
1313
public class PythonEngine : IDisposable
1414
{
15-
public static bool SoftShutdown { get; private set; }
15+
public static bool SoftShutdown => Runtime.SoftShutdown;
1616

1717
private static DelegateManager delegateManager;
1818
private static bool initialized;
@@ -171,7 +171,6 @@ public static void Initialize(IEnumerable<string> args, bool setSysArgv = true,
171171
delegateManager = new DelegateManager();
172172
Runtime.Initialize(initSigs, softShutdown);
173173
initialized = true;
174-
SoftShutdown = softShutdown;
175174
Exceptions.Clear();
176175

177176
// Make sure we clean up properly on app domain unload.

src/runtime/runtime.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,20 @@ public class Runtime
166166
/// </summary>
167167
internal static readonly Encoding PyEncoding = _UCS == 2 ? Encoding.Unicode : Encoding.UTF32;
168168

169+
public static bool SoftShutdown { get; private set; }
169170
private static PyReferenceCollection _typeRefs;
170171

171172
/// <summary>
172173
/// Initialize the runtime...
173174
/// </summary>
174175
internal static void Initialize(bool initSigs = false, bool softShutdown = false)
175176
{
177+
if (Environment.GetEnvironmentVariable("PYTHONNET_SOFT_SHUTDOWN") == "1")
178+
{
179+
softShutdown = true;
180+
}
181+
182+
SoftShutdown = softShutdown;
176183
if (Py_IsInitialized() == 0)
177184
{
178185
Py_InitializeEx(initSigs ? 1 : 0);

src/runtime/runtime_state.cs

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,33 @@ namespace Python.Runtime
99
{
1010
class RuntimeState
1111
{
12+
public static bool ShouldRestoreObjects { get; set; } = false;
13+
public static bool UseDummyGC { get; set; } = false;
14+
1215
public static void Save()
1316
{
1417
if (PySys_GetObject("dummy_gc") != IntPtr.Zero)
1518
{
1619
throw new Exception("Runtime State set already");
1720
}
1821

22+
IntPtr objs = IntPtr.Zero;
23+
if (ShouldRestoreObjects)
24+
{
25+
objs = PySet_New(IntPtr.Zero);
26+
foreach (var obj in PyGCGetObjects())
27+
{
28+
AddObjPtrToSet(objs, obj);
29+
}
30+
}
31+
1932
var modules = PySet_New(IntPtr.Zero);
2033
foreach (var name in GetModuleNames())
2134
{
2235
int res = PySet_Add(modules, name);
2336
PythonException.ThrowIfIsNotZero(res);
2437
}
2538

26-
var objs = PySet_New(IntPtr.Zero);
27-
foreach (var obj in PyGCGetObjects())
28-
{
29-
AddObjPtrToSet(objs, obj);
30-
}
3139

3240
var dummyGCHead = PyMem_Malloc(Marshal.SizeOf(typeof(PyGC_Head)));
3341
unsafe
@@ -43,7 +51,6 @@ public static void Save()
4351
PythonException.ThrowIfIsNotZero(res);
4452
XDecref(pyDummyGC);
4553

46-
AddObjPtrToSet(objs, modules);
4754
try
4855
{
4956
res = PySys_SetObject("initial_modules", modules);
@@ -54,17 +61,19 @@ public static void Save()
5461
XDecref(modules);
5562
}
5663

57-
AddObjPtrToSet(objs, objs);
58-
try
59-
{
60-
res = PySys_SetObject("initial_objs", objs);
61-
PythonException.ThrowIfIsNotZero(res);
62-
}
63-
finally
64+
if (ShouldRestoreObjects)
6465
{
65-
XDecref(objs);
66+
AddObjPtrToSet(objs, modules);
67+
try
68+
{
69+
res = PySys_SetObject("initial_objs", objs);
70+
PythonException.ThrowIfIsNotZero(res);
71+
}
72+
finally
73+
{
74+
XDecref(objs);
75+
}
6676
}
67-
6877
}
6978
}
7079

@@ -77,7 +86,10 @@ public static void Restore()
7786
}
7887
var dummyGC = PyLong_AsVoidPtr(dummyGCAddr);
7988
ResotreModules(dummyGC);
80-
RestoreObjects(dummyGC);
89+
if (ShouldRestoreObjects)
90+
{
91+
RestoreObjects(dummyGC);
92+
}
8193
}
8294

8395
private static void ResotreModules(IntPtr dummyGC)
@@ -92,16 +104,24 @@ private static void ResotreModules(IntPtr dummyGC)
92104
continue;
93105
}
94106
var module = PyDict_GetItem(modules, name);
95-
if (_PyObject_GC_IS_TRACKED(module))
107+
108+
if (UseDummyGC && _PyObject_GC_IS_TRACKED(module))
96109
{
97110
ExchangeGCChain(module, dummyGC);
98111
}
99-
PyDict_DelItem(modules, name);
112+
if (PyDict_DelItem(modules, name) != 0)
113+
{
114+
PyErr_Print();
115+
}
100116
}
101117
}
102118

103119
private static void RestoreObjects(IntPtr dummyGC)
104120
{
121+
if (!UseDummyGC)
122+
{
123+
throw new Exception("To prevent crash by _PyObject_GC_UNTRACK in Python internal, UseDummyGC should be enabled when using ResotreObjects");
124+
}
105125
var intialObjs = PySys_GetObject("initial_objs");
106126
Debug.Assert(intialObjs != null);
107127
foreach (var obj in PyGCGetObjects())

src/runtime/typemanager.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,6 @@ internal static void InitializeSlots(IntPtr type, Type impl, SlotsHolder slotsHo
818818
impl = impl.BaseType;
819819
}
820820

821-
bool canOverride = !PythonEngine.SoftShutdown;
822821
var native = NativeCode.Active;
823822

824823
// The garbage collection related slots always have to return 1 or 0

0 commit comments

Comments
 (0)
0