Skip to content

Commit a074813

Browse files
authored
Use a ReaderWriterLockSlim in RcwCache (#117792)
1 parent 7a14c76 commit a074813

File tree

1 file changed

+19
-4
lines changed
  • src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices

1 file changed

+19
-4
lines changed

src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ private static void AddWrapperToReferenceTrackerHandleCache(NativeObjectWrapper
12891289

12901290
private sealed class RcwCache
12911291
{
1292-
private readonly Lock _lock = new Lock(useTrivialWaits: true);
1292+
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
12931293
private readonly Dictionary<IntPtr, GCHandle> _cache = [];
12941294

12951295
/// <summary>
@@ -1301,7 +1301,8 @@ private sealed class RcwCache
13011301
/// <returns>The proxy object currently in the cache for <paramref name="comPointer"/> or the proxy object owned by <paramref name="wrapper"/> if no entry exists and the corresponding native wrapper.</returns>
13021302
public (NativeObjectWrapper actualWrapper, object actualProxy) GetOrAddProxyForComInstance(IntPtr comPointer, NativeObjectWrapper wrapper, object comProxy)
13031303
{
1304-
lock (_lock)
1304+
_lock.EnterWriteLock();
1305+
try
13051306
{
13061307
Debug.Assert(wrapper.ProxyHandle.Target == comProxy);
13071308
ref GCHandle rcwEntry = ref CollectionsMarshal.GetValueRefOrAddDefault(_cache, comPointer, out bool exists);
@@ -1336,11 +1337,16 @@ private sealed class RcwCache
13361337
// Return our target object.
13371338
return (wrapper, comProxy);
13381339
}
1340+
finally
1341+
{
1342+
_lock.ExitWriteLock();
1343+
}
13391344
}
13401345

13411346
public object? FindProxyForComInstance(IntPtr comPointer)
13421347
{
1343-
lock (_lock)
1348+
_lock.EnterReadLock();
1349+
try
13441350
{
13451351
if (_cache.TryGetValue(comPointer, out GCHandle existingHandle))
13461352
{
@@ -1357,11 +1363,16 @@ private sealed class RcwCache
13571363

13581364
return null;
13591365
}
1366+
finally
1367+
{
1368+
_lock.ExitReadLock();
1369+
}
13601370
}
13611371

13621372
public void Remove(IntPtr comPointer, NativeObjectWrapper wrapper)
13631373
{
1364-
lock (_lock)
1374+
_lock.EnterWriteLock();
1375+
try
13651376
{
13661377
// TryGetOrCreateObjectForComInstanceInternal may have put a new entry into the cache
13671378
// in the time between the GC cleared the contents of the GC handle but before the
@@ -1376,6 +1387,10 @@ public void Remove(IntPtr comPointer, NativeObjectWrapper wrapper)
13761387
cachedRef.Free();
13771388
}
13781389
}
1390+
finally
1391+
{
1392+
_lock.ExitWriteLock();
1393+
}
13791394
}
13801395
}
13811396

0 commit comments

Comments
 (0)