Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9b990c1

Browse files
committed
switched finalizer.cs to the new style references
1 parent 3b79019 commit 9b990c1

File tree

1 file changed

+45
-19
lines changed

1 file changed

+45
-19
lines changed

src/runtime/finalizer.cs

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,18 @@ public class CollectArgs : EventArgs
1717

1818
public class ErrorArgs : EventArgs
1919
{
20+
public ErrorArgs(Exception error)
21+
{
22+
Error = error ?? throw new ArgumentNullException(nameof(error));
23+
}
2024
public bool Handled { get; set; }
21-
public Exception Error { get; set; }
25+
public Exception Error { get; }
2226
}
2327

2428
public static readonly Finalizer Instance = new Finalizer();
2529

26-
public event EventHandler<CollectArgs> BeforeCollect;
27-
public event EventHandler<ErrorArgs> ErrorHandler;
30+
public event EventHandler<CollectArgs>? BeforeCollect;
31+
public event EventHandler<ErrorArgs>? ErrorHandler;
2832

2933
const int DefaultThreshold = 200;
3034
[DefaultValue(DefaultThreshold)]
@@ -47,29 +51,49 @@ public class ErrorArgs : EventArgs
4751
// Keep these declarations for compat even no FINALIZER_CHECK
4852
internal class IncorrectFinalizeArgs : EventArgs
4953
{
50-
public IntPtr Handle { get; internal set; }
51-
public ICollection<IntPtr> ImpactedObjects { get; internal set; }
54+
public IncorrectFinalizeArgs(IntPtr handle, IReadOnlyCollection<IntPtr> imacted)
55+
{
56+
Handle = handle;
57+
ImpactedObjects = imacted;
58+
}
59+
public IntPtr Handle { get; }
60+
public IReadOnlyCollection<IntPtr> ImpactedObjects { get; }
5261
}
5362

5463
internal class IncorrectRefCountException : Exception
5564
{
5665
public IntPtr PyPtr { get; internal set; }
57-
private string _message;
58-
public override string Message => _message;
66+
string? message;
67+
public override string Message
68+
{
69+
get
70+
{
71+
if (message is not null) return message;
72+
var gil = PythonEngine.AcquireLock();
73+
try
74+
{
75+
using var pyname = Runtime.PyObject_Str(new BorrowedReference(PyPtr));
76+
string name = Runtime.GetManagedString(pyname.BorrowOrThrow()) ?? Util.BadStr;
77+
message = $"<{name}> may has a incorrect ref count";
78+
}
79+
finally
80+
{
81+
PythonEngine.ReleaseLock(gil);
82+
}
83+
return message;
84+
}
85+
}
5986

6087
internal IncorrectRefCountException(IntPtr ptr)
6188
{
6289
PyPtr = ptr;
63-
IntPtr pyname = Runtime.PyObject_Str(PyPtr);
64-
string name = Runtime.GetManagedString(pyname);
65-
Runtime.XDecref(pyname);
66-
_message = $"<{name}> may has a incorrect ref count";
90+
6791
}
6892
}
6993

7094
internal delegate bool IncorrectRefCntHandler(object sender, IncorrectFinalizeArgs e);
7195
#pragma warning disable 414
72-
internal event IncorrectRefCntHandler IncorrectRefCntResolver = null;
96+
internal event IncorrectRefCntHandler? IncorrectRefCntResolver = null;
7397
#pragma warning restore 414
7498
internal bool ThrowIfUnhandleIncorrectRefCount { get; set; } = true;
7599

@@ -134,25 +158,23 @@ private void DisposeAll()
134158
if (!_objQueue.TryDequeue(out obj))
135159
continue;
136160

137-
Runtime.XDecref(obj);
161+
IntPtr copyForException = obj;
162+
Runtime.XDecref(StolenReference.Take(ref obj));
138163
try
139164
{
140165
Runtime.CheckExceptionOccurred();
141166
}
142167
catch (Exception e)
143168
{
144-
var errorArgs = new ErrorArgs
145-
{
146-
Error = e,
147-
};
169+
var errorArgs = new ErrorArgs(e);
148170

149171
ErrorHandler?.Invoke(this, errorArgs);
150172

151173
if (!errorArgs.Handled)
152174
{
153175
throw new FinalizationException(
154176
"Python object finalization failed",
155-
disposable: obj, innerException: e);
177+
disposable: copyForException, innerException: e);
156178
}
157179
}
158180
}
@@ -251,7 +273,11 @@ public class FinalizationException : Exception
251273
/// its reference count. This should only ever be called during debugging.
252274
/// When the result is disposed or finalized, the program will crash.
253275
/// </summary>
254-
public PyObject DebugGetObject() => new(this.Handle);
276+
public PyObject DebugGetObject()
277+
{
278+
IntPtr dangerousNoIncRefCopy = this.Handle;
279+
return new(StolenReference.Take(ref dangerousNoIncRefCopy));
280+
}
255281

256282
public FinalizationException(string message, IntPtr disposable, Exception innerException)
257283
: base(message, innerException)

0 commit comments

Comments
 (0)