Skip to content

Commit cd8abd1

Browse files
committed
Track Runtime run number. Assert, that PyObjects are only disposed in the same run they were created in.
1 parent ac336a8 commit cd8abd1

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

src/runtime/pyobject.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public partial class PyObject : DynamicObject, IDisposable
2626
public StackTrace Traceback { get; private set; }
2727
#endif
2828

29+
readonly long run = Runtime.GetRun();
2930
protected internal IntPtr obj = IntPtr.Zero;
3031

3132
public static PyObject None => new PyObject(new BorrowedReference(Runtime.PyNone));
@@ -188,6 +189,9 @@ protected virtual void Dispose(bool disposing)
188189
if (Runtime.Py_IsInitialized() == 0)
189190
throw new InvalidOperationException("Python runtime must be initialized");
190191

192+
if (this.run != Runtime.GetRun())
193+
throw new InvalidOperationException("Attempt to dispose PyObject from wrong run");
194+
191195
if (!Runtime.IsFinalizing)
192196
{
193197
long refcount = Runtime.Refcount(this.obj);

src/runtime/runtime.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ internal static Version PyVersion
8686
}
8787

8888
/// <summary>
89+
static long run = 0;
90+
91+
internal static long GetRun()
92+
{
93+
long runNumber = Interlocked.Read(ref run);
94+
System.Diagnostics.Debug.Assert(runNumber > 0,
95+
"This must only be called after Runtime is initialized at least once");
96+
return runNumber;
97+
}
98+
8999
/// Initialize the runtime...
90100
/// </summary>
91101
/// <remarks>Always call this method from the Main thread. After the
@@ -110,6 +120,7 @@ internal static void Initialize(bool initSigs = false, ShutdownMode mode = Shutd
110120
if (!interpreterAlreadyInitialized)
111121
{
112122
Py_InitializeEx(initSigs ? 1 : 0);
123+
Interlocked.Increment(ref run);
113124
if (PyEval_ThreadsInitialized() == 0)
114125
{
115126
PyEval_InitThreads();

0 commit comments

Comments
 (0)