Skip to content

Commit 1de7096

Browse files
committed
Use WeakReference<PythonType> instead of WeakReference
1 parent 2aca667 commit 1de7096

1 file changed

Lines changed: 26 additions & 28 deletions

File tree

src/core/IronPython/Runtime/Types/PythonType.cs

Lines changed: 26 additions & 28 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);
@@ -681,17 +680,15 @@ public void __setattr__(CodeContext/*!*/ context, string name, object value) {
681680

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

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

689-
foreach (WeakReference wr in subtypes) {
690-
if (wr.IsAlive) {
691-
PythonType pt = (PythonType)wr.Target;
692-
688+
foreach (var wr in subtypes) {
689+
if (wr.TryGetTarget(out PythonType pt)) {
693690
if (pt.PythonContext == null || pt.PythonContext == pc) {
694-
ret.AddNoLock(wr.Target);
691+
ret.AddNoLock(pt);
695692
}
696693
}
697694
}
@@ -1271,8 +1268,8 @@ internal void AddSlot(string name, PythonTypeSlot slot) {
12711268
private void ClearObjectNewInSubclasses(PythonType pt) {
12721269
lock (_subtypesLock) {
12731270
if (pt._subtypes != null) {
1274-
foreach (WeakReference wr in pt._subtypes) {
1275-
if (wr.Target is PythonType type) {
1271+
foreach (var wr in pt._subtypes) {
1272+
if (wr.TryGetTarget(out PythonType type)) {
12761273
type._objectNew = null;
12771274

12781275
ClearObjectNewInSubclasses(type);
@@ -1285,8 +1282,8 @@ private void ClearObjectNewInSubclasses(PythonType pt) {
12851282
private void ClearObjectInitInSubclasses(PythonType pt) {
12861283
lock (_subtypesLock) {
12871284
if (pt._subtypes != null) {
1288-
foreach (WeakReference wr in pt._subtypes) {
1289-
if (wr.Target is PythonType type) {
1285+
foreach (var wr in pt._subtypes) {
1286+
if (wr.TryGetTarget(out PythonType type)) {
12901287
type._objectInit = null;
12911288

12921289
ClearObjectInitInSubclasses(type);
@@ -2459,9 +2456,9 @@ private void EnsureInstanceCtor() {
24592456
#region Private implementation details
24602457

24612458
private void UpdateVersion() {
2462-
foreach (WeakReference wr in SubTypes) {
2463-
if (wr.IsAlive) {
2464-
((PythonType)wr.Target).UpdateVersion();
2459+
foreach (var wr in SubTypes) {
2460+
if (wr.TryGetTarget(out PythonType pt)) {
2461+
pt.UpdateVersion();
24652462
}
24662463
}
24672464

@@ -2497,25 +2494,26 @@ private void EnsureDict() {
24972494
/// </summary>
24982495
private void AddSubType(PythonType subtype) {
24992496
if (_subtypes == null) {
2500-
Interlocked.CompareExchange<List<WeakReference>>(ref _subtypes, new List<WeakReference>(), null);
2497+
Interlocked.CompareExchange(ref _subtypes, new List<WeakReference<PythonType>>(), null);
25012498
}
25022499

25032500
lock (_subtypesLock) {
2504-
_subtypes.Add(new WeakReference(subtype));
2501+
_subtypes.Add(new WeakReference<PythonType>(subtype));
25052502
}
25062503
}
25072504

25082505
private void RemoveSubType(PythonType subtype) {
2509-
int i = 0;
2510-
if (_subtypes != null) {
2511-
lock (_subtypesLock) {
2512-
while (i < _subtypes.Count) {
2513-
if (!_subtypes[i].IsAlive || _subtypes[i].Target == subtype) {
2514-
_subtypes.RemoveAt(i);
2515-
continue;
2516-
}
2517-
i++;
2506+
if (_subtypes is null) return;
2507+
2508+
lock (_subtypesLock) {
2509+
int i = 0;
2510+
while (i < _subtypes.Count) {
2511+
var wr = _subtypes[i];
2512+
if (!wr.TryGetTarget(out PythonType target) || target == subtype) {
2513+
_subtypes.RemoveAt(i);
2514+
continue;
25182515
}
2516+
i++;
25192517
}
25202518
}
25212519
}
@@ -2524,9 +2522,9 @@ private void RemoveSubType(PythonType subtype) {
25242522
/// Gets a list of weak references to all the subtypes of this class. May return null
25252523
/// if there are no subtypes of the class.
25262524
/// </summary>
2527-
private IList<WeakReference> SubTypes {
2525+
private IList<WeakReference<PythonType>> SubTypes {
25282526
get {
2529-
if (_subtypes == null) return _emptyWeakRef;
2527+
if (_subtypes == null) return Array.Empty<WeakReference<PythonType>>();
25302528

25312529
lock (_subtypesLock) {
25322530
return _subtypes.ToArray();

0 commit comments

Comments
 (0)