FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fixed sending PyObject across domain boundary · firstop/pythonnet@a8ef06c · GitHub

Repository navigation

Commit a8ef06c

Browse files
committed
fixed sending PyObject across domain boundary
removed debug code, that ensured Python GC list integrity
1 parent 2fdbf0e commit a8ef06c

26 files changed

Lines changed: 107 additions & 90 deletions

‎src/embed_tests/TestRuntime.cs‎

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,6 @@ public static void Py_IsInitializedValue()
3232
Assert.AreEqual(0, Runtime.Runtime.Py_IsInitialized());
3333
}
3434

35-
[Test]
36-
public static void IterAcrossRuns()
37-
{
38-
Runtime.Runtime.Py_Initialize();
39-
BorrowedReference builtins = Runtime.Runtime.PyEval_GetBuiltins();
40-
BorrowedReference iter = Runtime.Runtime.PyDict_GetItemString(builtins, "iter");
41-
42-
using var ownedIter = new NewReference(iter);
43-
Runtime.Runtime.Py_Finalize();
44-
45-
Runtime.Runtime.Py_Initialize();
46-
ownedIter.Dispose();
47-
Runtime.Runtime.Py_Finalize();
48-
}
49-
5035
[Test]
5136
public static void RefCountTest()
5237
{

‎src/runtime/ReflectedClrType.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Diagnostics;
3+
using System.Runtime.Serialization;
34

45
using static Python.Runtime.PythonException;
56

@@ -10,6 +11,7 @@ internal sealed class ReflectedClrType : PyType
1011
{
1112
private ReflectedClrType(StolenReference reference) : base(reference, prevalidated: true) { }
1213
internal ReflectedClrType(ReflectedClrType original) : base(original, prevalidated: true) { }
14+
ReflectedClrType(SerializationInfo info, StreamingContext context) : base(info, context) { }
1315

1416
internal ClassBase Impl => (ClassBase)ManagedType.GetManagedObject(this)!;
1517

‎src/runtime/classbase.cs‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,6 @@ public static NewReference tp_repr(BorrowedReference ob)
337337
/// </summary>
338338
public static void tp_dealloc(NewReference lastRef)
339339
{
340-
Runtime.PyGC_ValidateLists();
341340
Runtime.PyObject_GC_UnTrack(lastRef.Borrow());
342341

343342
CallClear(lastRef.Borrow());
@@ -347,12 +346,10 @@ public static void tp_dealloc(NewReference lastRef)
347346
Debug.Assert(deleted);
348347

349348
DecrefTypeAndFree(lastRef.Steal());
350-
Runtime.PyGC_ValidateLists();
351349
}
352350

353351
public static int tp_clear(BorrowedReference ob)
354352
{
355-
Runtime.PyGC_ValidateLists();
356353
GCHandle? gcHandle = TryGetGCHandle(ob);
357354
gcHandle?.Free();
358355

@@ -363,7 +360,6 @@ public static int tp_clear(BorrowedReference ob)
363360
}
364361

365362
ClearObjectDict(ob);
366-
Runtime.PyGC_ValidateLists();
367363
return 0;
368364
}
369365

‎src/runtime/classderived.cs‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ internal ClassDerivedObject(Type tp) : base(tp)
6969

7070
public new static void tp_dealloc(NewReference ob)
7171
{
72-
Runtime.PyGC_ValidateLists();
7372
var self = (CLRObject)GetManagedObject(ob.Borrow())!;
7473

7574
// don't let the python GC destroy this object
@@ -83,7 +82,6 @@ internal ClassDerivedObject(Type tp) : base(tp)
8382
GCHandle gc = GCHandle.Alloc(self, GCHandleType.Weak);
8483
SetGCHandle(ob.Borrow(), gc);
8584
oldHandle.Free();
86-
Runtime.PyGC_ValidateLists();
8785
}
8886

8987
/// <summary>

‎src/runtime/constructorbinding.cs‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,7 @@ public static int tp_traverse(BorrowedReference ob, IntPtr visit, IntPtr arg)
152152
var self = (ConstructorBinding?)GetManagedObject(ob);
153153
if (self is null) return 0;
154154

155-
Runtime.PyGC_ValidateLists();
156155
int res = PyVisit(self.typeToCreate, visit, arg);
157-
Runtime.PyGC_ValidateLists();
158156
return res;
159157
}
160158
}
@@ -237,9 +235,7 @@ public static int tp_traverse(BorrowedReference ob, IntPtr visit, IntPtr arg)
237235
var self = (BoundContructor?)GetManagedObject(ob);
238236
if (self is null) return 0;
239237

240-
Runtime.PyGC_ValidateLists();
241238
int res = PyVisit(self.typeToCreate, visit, arg);
242-
Runtime.PyGC_ValidateLists();
243239
return res;
244240
}
245241
}

‎src/runtime/extensiontype.cs‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ public static int tp_setattro(BorrowedReference ob, BorrowedReference key, Borro
7676

7777
public unsafe static void tp_dealloc(NewReference lastRef)
7878
{
79-
Runtime.PyGC_ValidateLists();
8079
Runtime.PyObject_GC_UnTrack(lastRef.Borrow());
8180

8281
tp_clear(lastRef.Borrow());
@@ -86,18 +85,15 @@ public unsafe static void tp_dealloc(NewReference lastRef)
8685

8786
// we must decref our type: https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_dealloc
8887
DecrefTypeAndFree(lastRef.Steal());
89-
Runtime.PyGC_ValidateLists();
9088
}
9189

9290
public static int tp_clear(BorrowedReference ob)
9391
{
94-
Runtime.PyGC_ValidateLists();
9592
GCHandle? gcHandle = TryGetGCHandle(ob);
9693
gcHandle?.Free();
9794
if (gcHandle is not null) SetGCHandle(ob, default);
9895

9996
int res = ClassBase.BaseUnmanagedClear(ob);
100-
Runtime.PyGC_ValidateLists();
10197
return res;
10298
}
10399

‎src/runtime/finalizer.cs‎

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -122,19 +122,30 @@ internal List<IntPtr> GetCollectedObjects()
122122
return _objQueue.Select(o => o.PyObj).ToList();
123123
}
124124

125-
internal void AddFinalizedObject(ref IntPtr obj, int run)
125+
internal void AddFinalizedObject(ref IntPtr obj, int run
126+
#if TRACE_ALLOC
127+
, StackTrace stackTrace
128+
#endif
129+
)
126130
{
127131
Debug.Assert(obj != IntPtr.Zero);
128132
if (!Enable)
129133
{
130134
return;
131135
}
132136

137+
Debug.Assert(Runtime.Refcount(new BorrowedReference(obj)) > 0);
138+
133139
#if FINALIZER_CHECK
134140
lock (_queueLock)
135141
#endif
136142
{
137-
this._objQueue.Enqueue(new PendingFinalization { PyObj = obj, RuntimeRun = run });
143+
this._objQueue.Enqueue(new PendingFinalization {
144+
PyObj = obj, RuntimeRun = run,
145+
#if TRACE_ALLOC
146+
StackTrace = stackTrace.ToString(),
147+
#endif
148+
});
138149
}
139150
obj = IntPtr.Zero;
140151
}
@@ -165,10 +176,12 @@ internal static void Shutdown()
165176
Instance.started = false;
166177
}
167178

168-
private void DisposeAll()
179+
internal nint DisposeAll()
169180
{
170181
if (_objQueue.IsEmpty && _derivedQueue.IsEmpty)
171-
return;
182+
return 0;
183+
184+
nint collected = 0;
172185

173186
BeforeCollect?.Invoke(this, new CollectArgs()
174187
{
@@ -200,16 +213,8 @@ private void DisposeAll()
200213
}
201214

202215
IntPtr copyForException = obj.PyObj;
203-
Runtime.PyGC_ValidateLists();
204-
var @ref = new BorrowedReference(obj.PyObj);
205-
nint refs = Runtime.Refcount(@ref);
206-
var type = Runtime.PyObject_TYPE(@ref);
207-
string typeName = Runtime.ToString(type);
208-
if (typeName == "<class 'clr.interop.PyErr'>")
209-
{
210-
211-
}
212216
Runtime.XDecref(StolenReference.Take(ref obj.PyObj));
217+
collected++;
213218
try
214219
{
215220
Runtime.CheckExceptionOccurred();
@@ -218,7 +223,6 @@ private void DisposeAll()
218223
{
219224
HandleFinalizationException(obj.PyObj, e);
220225
}
221-
Runtime.PyGC_ValidateLists();
222226
}
223227

224228
while (!_derivedQueue.IsEmpty)
@@ -241,6 +245,7 @@ private void DisposeAll()
241245
// matches correspdonging PyObject_GC_UnTrack
242246
// in ClassDerivedObject.tp_dealloc
243247
Runtime.PyObject_GC_Del(@ref.Steal());
248+
collected++;
244249

245250
gcHandle.Free();
246251
}
@@ -252,6 +257,7 @@ private void DisposeAll()
252257
Runtime.PyErr_Restore(errType.StealNullable(), errVal.StealNullable(), traceback.StealNullable());
253258
}
254259
}
260+
return collected;
255261
}
256262

257263
void HandleFinalizationException(IntPtr obj, Exception cause)
@@ -341,6 +347,9 @@ struct PendingFinalization
341347
{
342348
public IntPtr PyObj;
343349
public int RuntimeRun;
350+
#if TRACE_ALLOC
351+
public string StackTrace;
352+
#endif
344353
}
345354

346355
public class FinalizationException : Exception

‎src/runtime/metatype.cs‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,6 @@ public static NewReference mp_subscript(BorrowedReference tp, BorrowedReference
290290
/// </summary>
291291
public static void tp_dealloc(NewReference lastRef)
292292
{
293-
Runtime.PyGC_ValidateLists();
294293
// Fix this when we dont cheat on the handle for subclasses!
295294

296295
var flags = PyType.GetFlags(lastRef.Borrow());
@@ -318,7 +317,6 @@ public static void tp_dealloc(NewReference lastRef)
318317
// We must decref our type.
319318
// type_dealloc from PyType will use it to get tp_free so we must keep the value
320319
Runtime.XDecref(StolenReference.DangerousFromPointer(op.DangerousGetAddress()));
321-
Runtime.PyGC_ValidateLists();
322320
}
323321

324322
private static NewReference DoInstanceCheck(BorrowedReference tp, BorrowedReference args, bool checkType)

‎src/runtime/module.cs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Linq;
33
using System.Collections.Generic;
44
using System.Dynamic;
5+
using System.Runtime.Serialization;
56

67
namespace Python.Runtime
78
{
@@ -42,6 +43,9 @@ internal PyModule(in StolenReference reference) : base(reference)
4243
}
4344
}
4445

46+
protected PyModule(SerializationInfo info, StreamingContext context)
47+
: base(info, context) { }
48+
4549
private void InitializeBuiltins()
4650
{
4751
int res = Runtime.PyDict_SetItem(

‎src/runtime/moduleobject.cs‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -323,16 +323,12 @@ public static int tp_traverse(BorrowedReference ob, IntPtr visit, IntPtr arg)
323323
var self = (ModuleObject?)GetManagedObject(ob);
324324
if (self is null) return 0;
325325

326-
Runtime.PyGC_ValidateLists();
327326
Debug.Assert(self.dict == GetObjectDict(ob));
328327
int res = PyVisit(self.dict, visit, arg);
329-
Runtime.PyGC_ValidateLists();
330328
if (res != 0) return res;
331329
foreach (var attr in self.cache.Values)
332330
{
333-
Runtime.PyGC_ValidateLists();
334331
res = PyVisit(attr, visit, arg);
335-
Runtime.PyGC_ValidateLists();
336332
if (res != 0) return res;
337333
}
338334
return 0;

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL