Skip to content

Commit d587f79

Browse files
committed
Remove Lock from DefaultNamingSubSystem in benefit of ReaderWriterLockSlim
castleproject#565
1 parent 63971da commit d587f79

File tree

1 file changed

+59
-15
lines changed

1 file changed

+59
-15
lines changed

src/Castle.Windsor/MicroKernel/SubSystems/Naming/DefaultNamingSubSystem.cs

+59-15
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ namespace Castle.MicroKernel.SubSystems.Naming
1818
using System.Collections.Generic;
1919
using System.Linq;
2020
using System.Reflection;
21+
using System.Threading;
2122

2223
using Castle.Core.Internal;
2324
using Castle.MicroKernel.Util;
2425

2526
[Serializable]
2627
public class DefaultNamingSubSystem : AbstractSubSystem, INamingSubSystem
2728
{
28-
protected readonly Lock @lock = Lock.Create();
29+
private readonly ReaderWriterLockSlim @lock = new ReaderWriterLockSlim();
2930

3031
/// <summary>
3132
/// Map(String, IHandler) to map component names to <see cref="IHandler" /> Items in this dictionary are sorted in insertion order.
@@ -65,12 +66,17 @@ protected IDictionary<string, IHandler> HandlerByNameCache
6566
{
6667
return cache;
6768
}
68-
using (@lock.ForWriting())
69+
@lock.EnterWriteLock();
70+
try
6971
{
7072
cache = new Dictionary<string, IHandler>(name2Handler, name2Handler.Comparer);
7173
handlerByNameCache = cache;
7274
return cache;
7375
}
76+
finally
77+
{
78+
@lock.ExitWriteLock();
79+
}
7480
}
7581
}
7682

@@ -83,7 +89,8 @@ protected IDictionary<Type, IHandler> HandlerByServiceCache
8389
{
8490
return cache;
8591
}
86-
using (@lock.ForWriting())
92+
@lock.EnterWriteLock();
93+
try
8794
{
8895
cache = new Dictionary<Type, IHandler>(service2Handler.Count, service2Handler.Comparer);
8996
foreach (var item in service2Handler)
@@ -93,6 +100,10 @@ protected IDictionary<Type, IHandler> HandlerByServiceCache
93100
handlerByServiceCache = cache;
94101
return cache;
95102
}
103+
finally
104+
{
105+
@lock.ExitWriteLock();
106+
}
96107
}
97108
}
98109

@@ -223,17 +234,30 @@ public virtual IHandler[] GetHandlers(Type service)
223234
}
224235

225236
IHandler[] result;
226-
using (var locker = @lock.ForReadingUpgradeable())
237+
@lock.EnterUpgradeableReadLock();
238+
try
227239
{
228240
if (handlerListsByTypeCache.TryGetValue(service, out result))
229241
{
230242
return result;
231243
}
232244
result = GetHandlersNoLock(service);
233-
234-
locker.Upgrade();
235-
handlerListsByTypeCache[service] = result;
245+
@lock.EnterWriteLock();
246+
try
247+
{
248+
handlerListsByTypeCache[service] = result;
249+
}
250+
finally
251+
{
252+
@lock.ExitWriteLock();
253+
}
254+
236255
}
256+
finally
257+
{
258+
@lock.ExitUpgradeableReadLock();
259+
}
260+
237261

238262
return result;
239263
}
@@ -242,7 +266,8 @@ public virtual IHandler[] GetHandlers(Type service)
242266
public virtual void Register(IHandler handler)
243267
{
244268
var name = handler.ComponentModel.Name;
245-
using (@lock.ForWriting())
269+
@lock.EnterReadLock();
270+
try
246271
{
247272
try
248273
{
@@ -255,6 +280,7 @@ public virtual void Register(IHandler handler)
255280
"Component {0} could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name.",
256281
name));
257282
}
283+
258284
var serviceSelector = GetServiceSelector(handler);
259285
foreach (var service in handler.ComponentModel.Services)
260286
{
@@ -265,29 +291,47 @@ public virtual void Register(IHandler handler)
265291
service2Handler[service] = handlerForService;
266292
}
267293
}
294+
268295
InvalidateCache();
269296
}
297+
finally
298+
{
299+
@lock.ExitReadLock();
300+
}
270301
}
271302

272303
protected IHandler[] GetAssignableHandlersNoFiltering(Type service)
273304
{
274305
IHandler[] result;
275-
using (var locker = @lock.ForReadingUpgradeable())
306+
@lock.EnterUpgradeableReadLock();
307+
try
276308
{
277309
if (assignableHandlerListsByTypeCache.TryGetValue(service, out result))
278310
{
279311
return result;
280312
}
281313

282-
locker.Upgrade();
283-
if (assignableHandlerListsByTypeCache.TryGetValue(service, out result))
314+
@lock.EnterWriteLock();
315+
try
284316
{
285-
return result;
317+
if (assignableHandlerListsByTypeCache.TryGetValue(service, out result))
318+
{
319+
return result;
320+
}
321+
322+
result = name2Handler.Values.Where(h => h.SupportsAssignable(service)).ToArray();
323+
assignableHandlerListsByTypeCache[service] = result;
324+
}
325+
finally
326+
{
327+
@lock.ExitWriteLock();
286328
}
287-
result = name2Handler.Values.Where(h => h.SupportsAssignable(service)).ToArray();
288-
assignableHandlerListsByTypeCache[service] = result;
329+
330+
}
331+
finally
332+
{
333+
@lock.ExitUpgradeableReadLock();
289334
}
290-
291335
return result;
292336
}
293337

0 commit comments

Comments
 (0)