Skip to content

Commit 91786b4

Browse files
committed
Use WeakReference<PythonType> instead of WeakReference
1 parent 2e5bb60 commit 91786b4

File tree

1 file changed

+27
-29
lines changed

1 file changed

+27
-29
lines changed

Src/IronPython/Runtime/Types/PythonType.cs

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public partial class PythonType : IPythonMembersList, IDynamicMetaObjectProvider
3939
private PythonTypeAttributes _attrs; // attributes of the type
4040
private int _flags; // CPython-like flags on the type
4141
private int _version = GetNextVersion(); // version of the type
42-
private List<WeakReference> _subtypes; // all of the subtypes of the PythonType
42+
private List<WeakReference<PythonType>> _subtypes; // all of the subtypes of the PythonType
4343
private PythonContext _pythonContext; // the context the type was created from, or null for system types.
4444
private bool? _objectNew, _objectInit; // true if the type doesn't override __new__ / __init__ from object.
4545
internal Dictionary<CachedGetKey, FastGetBase> _cachedGets; // cached gets on user defined type instances
@@ -76,7 +76,6 @@ public partial class PythonType : IPythonMembersList, IDynamicMetaObjectProvider
7676
[MultiRuntimeAware]
7777
private static int MasterVersion = 1;
7878
private static readonly CommonDictionaryStorage _pythonTypes = new CommonDictionaryStorage();
79-
private static readonly WeakReference[] _emptyWeakRef = Array.Empty<WeakReference>();
8079
private static readonly object _subtypesLock = new object();
8180
internal static readonly Func<string, Exception, Exception> DefaultMakeException = (message, innerException) => new Exception(message, innerException);
8281
internal static readonly Func<string, Exception> DefaultMakeExceptionNoInnerException = (message) => new Exception(message);
@@ -680,17 +679,15 @@ public void __setattr__(CodeContext/*!*/ context, string name, object value) {
680679

681680
public PythonList __subclasses__(CodeContext/*!*/ context) {
682681
PythonList ret = new PythonList();
683-
IList<WeakReference> subtypes = SubTypes;
682+
var subtypes = SubTypes;
684683

685684
if (subtypes != null) {
686685
PythonContext pc = context.LanguageContext;
687686

688-
foreach (WeakReference wr in subtypes) {
689-
if (wr.IsAlive) {
690-
PythonType pt = (PythonType)wr.Target;
691-
687+
foreach (var wr in subtypes) {
688+
if (wr.TryGetTarget(out PythonType pt)) {
692689
if (pt.PythonContext == null || pt.PythonContext == pc) {
693-
ret.AddNoLock(wr.Target);
690+
ret.AddNoLock(pt);
694691
}
695692
}
696693
}
@@ -1270,8 +1267,8 @@ internal void AddSlot(string name, PythonTypeSlot slot) {
12701267
private void ClearObjectNewInSubclasses(PythonType pt) {
12711268
lock (_subtypesLock) {
12721269
if (pt._subtypes != null) {
1273-
foreach (WeakReference wr in pt._subtypes) {
1274-
if (wr.Target is PythonType type) {
1270+
foreach (var wr in pt._subtypes) {
1271+
if (wr.TryGetTarget(out PythonType type)) {
12751272
type._objectNew = null;
12761273

12771274
ClearObjectNewInSubclasses(type);
@@ -1284,8 +1281,8 @@ private void ClearObjectNewInSubclasses(PythonType pt) {
12841281
private void ClearObjectInitInSubclasses(PythonType pt) {
12851282
lock (_subtypesLock) {
12861283
if (pt._subtypes != null) {
1287-
foreach (WeakReference wr in pt._subtypes) {
1288-
if (wr.Target is PythonType type) {
1284+
foreach (var wr in pt._subtypes) {
1285+
if (wr.TryGetTarget(out PythonType type)) {
12891286
type._objectInit = null;
12901287

12911288
ClearObjectInitInSubclasses(type);
@@ -2465,9 +2462,9 @@ private void EnsureInstanceCtor() {
24652462
#region Private implementation details
24662463

24672464
private void UpdateVersion() {
2468-
foreach (WeakReference wr in SubTypes) {
2469-
if (wr.IsAlive) {
2470-
((PythonType)wr.Target).UpdateVersion();
2465+
foreach (var wr in SubTypes) {
2466+
if (wr.TryGetTarget(out PythonType pt)) {
2467+
pt.UpdateVersion();
24712468
}
24722469
}
24732470

@@ -2497,31 +2494,32 @@ private void EnsureDict() {
24972494
null);
24982495
}
24992496
}
2500-
2497+
25012498
/// <summary>
25022499
/// Internal helper function to add a subtype
25032500
/// </summary>
25042501
private void AddSubType(PythonType subtype) {
25052502
if (_subtypes == null) {
2506-
Interlocked.CompareExchange<List<WeakReference>>(ref _subtypes, new List<WeakReference>(), null);
2503+
Interlocked.CompareExchange(ref _subtypes, new List<WeakReference<PythonType>>(), null);
25072504
}
25082505

25092506
lock (_subtypesLock) {
2510-
_subtypes.Add(new WeakReference(subtype));
2507+
_subtypes.Add(new WeakReference<PythonType>(subtype));
25112508
}
25122509
}
25132510

25142511
private void RemoveSubType(PythonType subtype) {
2515-
int i = 0;
2516-
if (_subtypes != null) {
2517-
lock (_subtypesLock) {
2518-
while (i < _subtypes.Count) {
2519-
if (!_subtypes[i].IsAlive || _subtypes[i].Target == subtype) {
2520-
_subtypes.RemoveAt(i);
2521-
continue;
2522-
}
2523-
i++;
2512+
if (_subtypes is null) return;
2513+
2514+
lock (_subtypesLock) {
2515+
int i = 0;
2516+
while (i < _subtypes.Count) {
2517+
var wr = _subtypes[i];
2518+
if (!wr.TryGetTarget(out PythonType target) || target == subtype) {
2519+
_subtypes.RemoveAt(i);
2520+
continue;
25242521
}
2522+
i++;
25252523
}
25262524
}
25272525
}
@@ -2530,9 +2528,9 @@ private void RemoveSubType(PythonType subtype) {
25302528
/// Gets a list of weak references to all the subtypes of this class. May return null
25312529
/// if there are no subtypes of the class.
25322530
/// </summary>
2533-
private IList<WeakReference> SubTypes {
2531+
private IList<WeakReference<PythonType>> SubTypes {
25342532
get {
2535-
if (_subtypes == null) return _emptyWeakRef;
2533+
if (_subtypes == null) return Array.Empty<WeakReference<PythonType>>();
25362534

25372535
lock (_subtypesLock) {
25382536
return _subtypes.ToArray();

0 commit comments

Comments
 (0)