-
Notifications
You must be signed in to change notification settings - Fork 471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecate Lock
and ModuleScope
's public type cache API
#391
Changes from all commits
f6642ee
0606a55
e0ca272
0b37d14
88c80a2
91b091c
41c0dd2
8885558
f8e69e5
aa7436b
5bd3e48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,12 +18,11 @@ namespace Castle.Components.DictionaryAdapter.Xml | |
using System; | ||
using System.Collections.Generic; | ||
using System.Threading; | ||
using Castle.Core.Internal; | ||
|
||
public class SingletonDispenser<TKey, TItem> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If SingletonDispenser is an internal utility why is it public? Should it become [Obsolete] too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or it should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd keep this pull request focused on deprecating |
||
where TItem : class | ||
{ | ||
private readonly Lock locker; | ||
private readonly ReaderWriterLockSlim locker; | ||
private readonly Dictionary<TKey, object> items; | ||
private readonly Func<TKey, TItem> factory; | ||
|
||
|
@@ -32,7 +31,7 @@ public SingletonDispenser(Func<TKey, TItem> factory) | |
if (factory == null) | ||
throw Error.ArgumentNull("factory"); | ||
|
||
this.locker = new SlimReadWriteLock(); | ||
this.locker = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); | ||
this.items = new Dictionary<TKey, object>(); | ||
this.factory = factory; | ||
} | ||
|
@@ -53,22 +52,44 @@ private TItem GetOrCreate(TKey key) | |
|
||
private bool TryGetExistingItem(TKey key, out object item) | ||
{ | ||
using (locker.ForReading()) | ||
locker.EnterReadLock(); | ||
try | ||
{ | ||
if (items.TryGetValue(key, out item)) | ||
{ | ||
return true; | ||
} | ||
} | ||
finally | ||
{ | ||
locker.ExitReadLock(); | ||
} | ||
|
||
using (var hold = locker.ForReadingUpgradeable()) | ||
locker.EnterUpgradeableReadLock(); | ||
try | ||
{ | ||
if (items.TryGetValue(key, out item)) | ||
{ | ||
return true; | ||
|
||
using (hold.Upgrade()) | ||
items[key] = item = new ManualResetEvent(false); | ||
} | ||
else | ||
{ | ||
locker.EnterWriteLock(); | ||
try | ||
{ | ||
items[key] = item = new ManualResetEvent(false); | ||
return false; | ||
} | ||
finally | ||
{ | ||
locker.ExitWriteLock(); | ||
} | ||
} | ||
} | ||
finally | ||
{ | ||
locker.ExitUpgradeableReadLock(); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
private TItem WaitForCreate(TKey key, object item) | ||
|
@@ -77,8 +98,15 @@ private TItem WaitForCreate(TKey key, object item) | |
|
||
handle.WaitOne(); | ||
|
||
using (locker.ForReading()) | ||
return (TItem) items[key]; | ||
locker.EnterReadLock(); | ||
try | ||
{ | ||
return (TItem)items[key]; | ||
} | ||
finally | ||
{ | ||
locker.ExitReadLock(); | ||
} | ||
} | ||
|
||
private TItem Create(TKey key, object item) | ||
|
@@ -87,8 +115,15 @@ private TItem Create(TKey key, object item) | |
|
||
var result = factory(key); | ||
|
||
using (locker.ForWriting()) | ||
locker.EnterWriteLock(); | ||
try | ||
{ | ||
items[key] = result; | ||
} | ||
finally | ||
{ | ||
locker.ExitWriteLock(); | ||
} | ||
|
||
handle.Set(); | ||
return result; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,10 @@ | |
namespace Castle.Core.Internal | ||
{ | ||
using System; | ||
using System.ComponentModel; | ||
|
||
[Obsolete("Consider using `System.Threading.ReaderWriterLockSlim` instead of `Lock` and related types.")] // TODO: Remove this type. | ||
[EditorBrowsable(EditorBrowsableState.Never)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've put |
||
public interface ILockHolder:IDisposable | ||
{ | ||
bool LockAcquired { get; } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not a fan of disabling
[Obsolete]
-related warnings CS0612 and CS0618 solution-wide, but this still seems better than sprinkling#pragma warning disable
s and#pragma warning restore
s across the whole code base.[assembly: SuppressMessage]
would have been nice, but I couldn't get it to work with these warnings.We should remove this again right before releasing Castle Core 5.0.0.