Skip to content

Commit bd7c7b4

Browse files
committed
Use WeakReference<PythonType> instead of WeakReference
1 parent 684be43 commit bd7c7b4

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
@@ -40,7 +40,7 @@ public partial class PythonType : IPythonMembersList, IDynamicMetaObjectProvider
4040
private PythonTypeAttributes _attrs; // attributes of the type
4141
private int _flags; // CPython-like flags on the type
4242
private int _version = GetNextVersion(); // version of the type
43-
private List<WeakReference> _subtypes; // all of the subtypes of the PythonType
43+
private List<WeakReference<PythonType>> _subtypes; // all of the subtypes of the PythonType
4444
private PythonContext _pythonContext; // the context the type was created from, or null for system types.
4545
private bool? _objectNew, _objectInit; // true if the type doesn't override __new__ / __init__ from object.
4646
internal Dictionary<CachedGetKey, FastGetBase> _cachedGets; // cached gets on user defined type instances
@@ -79,7 +79,6 @@ public partial class PythonType : IPythonMembersList, IDynamicMetaObjectProvider
7979
private static int MasterVersion = 1;
8080
private static readonly CommonDictionaryStorage _pythonTypes = new CommonDictionaryStorage();
8181
internal static readonly PythonType _pythonTypeType = DynamicHelpers.GetPythonTypeFromType(typeof(PythonType));
82-
private static readonly WeakReference[] _emptyWeakRef = new WeakReference[0];
8382
private static object _subtypesLock = new object();
8483
internal static readonly Func<string, Exception, Exception> DefaultMakeException = (message, innerException) => new Exception(message, innerException);
8584
internal static readonly Func<string, Exception> DefaultMakeExceptionNoInnerException = (message) => new Exception(message);
@@ -658,17 +657,15 @@ public void __setattr__(CodeContext/*!*/ context, string name, object value) {
658657

659658
public PythonList __subclasses__(CodeContext/*!*/ context) {
660659
PythonList ret = new PythonList();
661-
IList<WeakReference> subtypes = SubTypes;
660+
var subtypes = SubTypes;
662661

663662
if (subtypes != null) {
664663
PythonContext pc = context.LanguageContext;
665664

666-
foreach (WeakReference wr in subtypes) {
667-
if (wr.IsAlive) {
668-
PythonType pt = (PythonType)wr.Target;
669-
665+
foreach (var wr in subtypes) {
666+
if (wr.TryGetTarget(out PythonType pt)) {
670667
if (pt.PythonContext == null || pt.PythonContext == pc) {
671-
ret.AddNoLock(wr.Target);
668+
ret.AddNoLock(pt);
672669
}
673670
}
674671
}
@@ -1267,8 +1264,8 @@ internal void AddSlot(string name, PythonTypeSlot slot) {
12671264
private void ClearObjectNewInSubclasses(PythonType pt) {
12681265
lock (_subtypesLock) {
12691266
if (pt._subtypes != null) {
1270-
foreach (WeakReference wr in pt._subtypes) {
1271-
if (wr.Target is PythonType type) {
1267+
foreach (var wr in pt._subtypes) {
1268+
if (wr.TryGetTarget(out PythonType type)) {
12721269
type._objectNew = null;
12731270

12741271
ClearObjectNewInSubclasses(type);
@@ -1281,8 +1278,8 @@ private void ClearObjectNewInSubclasses(PythonType pt) {
12811278
private void ClearObjectInitInSubclasses(PythonType pt) {
12821279
lock (_subtypesLock) {
12831280
if (pt._subtypes != null) {
1284-
foreach (WeakReference wr in pt._subtypes) {
1285-
if (wr.Target is PythonType type) {
1281+
foreach (var wr in pt._subtypes) {
1282+
if (wr.TryGetTarget(out PythonType type)) {
12861283
type._objectInit = null;
12871284

12881285
ClearObjectInitInSubclasses(type);
@@ -2452,9 +2449,9 @@ private void EnsureInstanceCtor() {
24522449
#region Private implementation details
24532450

24542451
private void UpdateVersion() {
2455-
foreach (WeakReference wr in SubTypes) {
2456-
if (wr.IsAlive) {
2457-
((PythonType)wr.Target).UpdateVersion();
2452+
foreach (var wr in SubTypes) {
2453+
if (wr.TryGetTarget(out PythonType pt)) {
2454+
pt.UpdateVersion();
24582455
}
24592456
}
24602457

@@ -2484,31 +2481,32 @@ private void EnsureDict() {
24842481
null);
24852482
}
24862483
}
2487-
2484+
24882485
/// <summary>
24892486
/// Internal helper function to add a subtype
24902487
/// </summary>
24912488
private void AddSubType(PythonType subtype) {
24922489
if (_subtypes == null) {
2493-
Interlocked.CompareExchange<List<WeakReference>>(ref _subtypes, new List<WeakReference>(), null);
2490+
Interlocked.CompareExchange(ref _subtypes, new List<WeakReference<PythonType>>(), null);
24942491
}
24952492

24962493
lock (_subtypesLock) {
2497-
_subtypes.Add(new WeakReference(subtype));
2494+
_subtypes.Add(new WeakReference<PythonType>(subtype));
24982495
}
24992496
}
25002497

25012498
private void RemoveSubType(PythonType subtype) {
2502-
int i = 0;
2503-
if (_subtypes != null) {
2504-
lock (_subtypesLock) {
2505-
while (i < _subtypes.Count) {
2506-
if (!_subtypes[i].IsAlive || _subtypes[i].Target == subtype) {
2507-
_subtypes.RemoveAt(i);
2508-
continue;
2509-
}
2510-
i++;
2499+
if (_subtypes is null) return;
2500+
2501+
lock (_subtypesLock) {
2502+
int i = 0;
2503+
while (i < _subtypes.Count) {
2504+
var wr = _subtypes[i];
2505+
if (!wr.TryGetTarget(out PythonType target) || target == subtype) {
2506+
_subtypes.RemoveAt(i);
2507+
continue;
25112508
}
2509+
i++;
25122510
}
25132511
}
25142512
}
@@ -2517,9 +2515,9 @@ private void RemoveSubType(PythonType subtype) {
25172515
/// Gets a list of weak references to all the subtypes of this class. May return null
25182516
/// if there are no subtypes of the class.
25192517
/// </summary>
2520-
private IList<WeakReference> SubTypes {
2518+
private IList<WeakReference<PythonType>> SubTypes {
25212519
get {
2522-
if (_subtypes == null) return _emptyWeakRef;
2520+
if (_subtypes == null) return Array.Empty<WeakReference<PythonType>>();
25232521

25242522
lock (_subtypesLock) {
25252523
return _subtypes.ToArray();

0 commit comments

Comments
 (0)