Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1cf616d

Browse files
authored
Merge pull request#1712 from losttech/bugs/ShutdownSegFault
On shutdown from Python release all slot holders
2 parents0e57cdd +58bd58c commit1cf616d

File tree

7 files changed

+37
-24
lines changed

7 files changed

+37
-24
lines changed

‎pythonnet.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Repo", "Repo", "{441A0123-F
2525
EndProject
2626
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") ="CI","CI","{D301657F-5EAF-4534-B280-B858D651B2E5}"
2727
ProjectSection(SolutionItems) =preProject
28+
.github\workflows\ARM.yml= .github\workflows\ARM.yml
2829
.github\workflows\main.yml= .github\workflows\main.yml
2930
.github\workflows\nuget-preview.yml= .github\workflows\nuget-preview.yml
3031
EndProjectSection

‎pythonnet/__init__.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def set_runtime(runtime):
1616

1717

1818
defset_default_runtime()->None:
19-
ifsys.platform=='win32':
19+
ifsys.platform=="win32":
2020
set_runtime(clr_loader.get_netfx())
2121
else:
2222
set_runtime(clr_loader.get_mono())
@@ -36,22 +36,23 @@ def load():
3636
set_default_runtime()
3737

3838
dll_path=join(dirname(__file__),"runtime","Python.Runtime.dll")
39-
39+
4040
_LOADER_ASSEMBLY=_RUNTIME.get_assembly(dll_path)
4141

4242
func=_LOADER_ASSEMBLY["Python.Runtime.Loader.Initialize"]
43-
iffunc(''.encode("utf8"))!=0:
43+
iffunc(b"")!=0:
4444
raiseRuntimeError("Failed to initialize Python.Runtime.dll")
4545

4646
importatexit
47+
4748
atexit.register(unload)
4849

4950

5051
defunload():
5152
global_RUNTIME
5253
if_LOADER_ASSEMBLYisnotNone:
5354
func=_LOADER_ASSEMBLY["Python.Runtime.Loader.Shutdown"]
54-
iffunc(b"")!=0:
55+
iffunc(b"full_shutdown")!=0:
5556
raiseRuntimeError("Failed to call Python.NET shutdown")
5657

5758
if_RUNTIMEisnotNone:

‎src/runtime/Runtime.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ private static string GetDefaultDllName(Version version)
5454
}
5555

5656
privatestaticbool_isInitialized=false;
57-
5857
internalstaticboolIsInitialized=>_isInitialized;
58+
privatestaticbool_typesInitialized=false;
59+
internalstaticboolTypeManagerInitialized=>_typesInitialized;
5960
internalstaticreadonlyboolIs32Bit=IntPtr.Size==4;
6061

6162
// .NET core: System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
@@ -151,6 +152,7 @@ internal static void Initialize(bool initSigs = false)
151152
ClassManager.Reset();
152153
ClassDerivedObject.Reset();
153154
TypeManager.Initialize();
155+
_typesInitialized=true;
154156

155157
// Initialize modules that depend on the runtime class.
156158
AssemblyManager.Initialize();
@@ -273,6 +275,7 @@ internal static void Shutdown()
273275
NullGCHandles(ExtensionType.loadedExtensions);
274276
ClassManager.RemoveClasses();
275277
TypeManager.RemoveTypes();
278+
_typesInitialized=false;
276279

277280
MetaType.Release();
278281
PyCLRMetaType.Dispose();
@@ -293,9 +296,10 @@ internal static void Shutdown()
293296
Finalizer.Shutdown();
294297
InternString.Shutdown();
295298

299+
ResetPyMembers();
300+
296301
if(!HostedInPython)
297302
{
298-
ResetPyMembers();
299303
GC.Collect();
300304
GC.WaitForPendingFinalizers();
301305
PyGILState_Release(state);
@@ -312,7 +316,6 @@ internal static void Shutdown()
312316
}
313317
else
314318
{
315-
ResetPyMembers();
316319
PyGILState_Release(state);
317320
}
318321
}

‎src/runtime/TypeManager.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,21 @@ internal static void Initialize()
5151

5252
internalstaticvoidRemoveTypes()
5353
{
54-
foreach(vartypeincache.Values)
54+
if(Runtime.HostedInPython)
5555
{
56-
if(Runtime.HostedInPython
57-
&&_slotsHolders.TryGetValue(type,outvarholder))
56+
foreach(varholderin_slotsHolders)
5857
{
5958
// If refcount > 1, it needs to reset the managed slot,
6059
// otherwise it can dealloc without any trick.
61-
if(Runtime.Refcount(type)>1)
60+
if(holder.Key.Refcount>1)
6261
{
63-
holder.ResetSlots();
62+
holder.Value.ResetSlots();
6463
}
6564
}
65+
}
66+
67+
foreach(vartypeincache.Values)
68+
{
6669
type.Dispose();
6770
}
6871
cache.Clear();
@@ -507,7 +510,7 @@ internal static PyType CreateMetaType(Type impl, out SlotsHolder slotsHolder)
507510
{
508511
throwPythonException.ThrowLastAsClrException();
509512
}
510-
513+
511514
BorrowedReferencedict=Util.ReadRef(type,TypeOffset.tp_dict);
512515
using(varmod=Runtime.PyString_FromString("clr._internal"))
513516
Runtime.PyDict_SetItemString(dict,"__module__",mod.Borrow());
@@ -726,6 +729,7 @@ internal static void CopySlot(BorrowedReference from, BorrowedReference to, int
726729

727730
internalstaticSlotsHolderCreateSlotsHolder(PyTypetype)
728731
{
732+
type=newPyType(type);
729733
varholder=newSlotsHolder(type);
730734
_slotsHolders.Add(type,holder);
731735
returnholder;
@@ -828,6 +832,7 @@ public void ResetSlots()
828832
varmetatype=Runtime.PyObject_TYPE(Type);
829833
ManagedType.TryFreeGCHandle(Type,metatype);
830834
}
835+
Runtime.PyType_Modified(Type);
831836
}
832837

833838
publicstaticIntPtrGetDefaultSlot(intoffset)

‎src/runtime/Types/ClassDerived.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@ protected override NewReference NewObjectToPython(object obj, BorrowedReference
5959
// Decrement the python object's reference count.
6060
// This doesn't actually destroy the object, it just sets the reference to this object
6161
// to be a weak reference and it will be destroyed when the C# object is destroyed.
62-
if(!self.IsNull())
63-
{
64-
Runtime.XDecref(self.Steal());
65-
}
62+
Runtime.XDecref(self.Steal());
6663

6764
returnConverter.ToPython(obj,type.Value);
6865
}
@@ -942,13 +939,16 @@ internal static void Finalize(IntPtr derived)
942939

943940
vartype=Runtime.PyObject_TYPE(@ref.Borrow());
944941

945-
// rare case when it's needed
946-
// matches correspdonging PyObject_GC_UnTrack
947-
// in ClassDerivedObject.tp_dealloc
948-
Runtime.PyObject_GC_Del(@ref.Steal());
942+
if(!Runtime.HostedInPython||Runtime.TypeManagerInitialized)
943+
{
944+
// rare case when it's needed
945+
// matches correspdonging PyObject_GC_UnTrack
946+
// in ClassDerivedObject.tp_dealloc
947+
Runtime.PyObject_GC_Del(@ref.Steal());
949948

950-
// must decref our type
951-
Runtime.XDecref(StolenReference.DangerousFromPointer(type.DangerousGetAddress()));
949+
// must decref our type
950+
Runtime.XDecref(StolenReference.DangerousFromPointer(type.DangerousGetAddress()));
951+
}
952952
}
953953

954954
internalstaticFieldInfo?GetPyObjField(Typetype)=>type.GetField(PyObjName,PyObjFlags);

‎src/runtime/Types/ModuleObject.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,6 @@ public static Assembly AddReference(string name)
542542
/// <returns>The Type object</returns>
543543

544544
[ModuleFunction]
545-
[ForbidPythonThreads]
546545
publicstaticTypeGetClrType(Typetype)
547546
{
548547
returntype;

‎tests/test_engine.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,7 @@ def test_run_string():
4141
assertsys.multiline_worked==1
4242

4343
PythonEngine.ReleaseLock()
44+
45+
deftest_leak_type():
46+
importclr
47+
sys._leaked_intptr=clr.GetClrType(System.IntPtr)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp