diff --git a/src/Castle.Facilities.AspNet.Mvc.Tests/Castle.Facilities.AspNet.Mvc.Tests.csproj b/src/Castle.Facilities.AspNet.Mvc.Tests/Castle.Facilities.AspNet.Mvc.Tests.csproj index f083f4ae0a..c2c058efc4 100644 --- a/src/Castle.Facilities.AspNet.Mvc.Tests/Castle.Facilities.AspNet.Mvc.Tests.csproj +++ b/src/Castle.Facilities.AspNet.Mvc.Tests/Castle.Facilities.AspNet.Mvc.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/Castle.Facilities.AspNet.SystemWeb.Tests/Castle.Facilities.AspNet.SystemWeb.Tests.csproj b/src/Castle.Facilities.AspNet.SystemWeb.Tests/Castle.Facilities.AspNet.SystemWeb.Tests.csproj index 03c91f987a..27ca9073ce 100644 --- a/src/Castle.Facilities.AspNet.SystemWeb.Tests/Castle.Facilities.AspNet.SystemWeb.Tests.csproj +++ b/src/Castle.Facilities.AspNet.SystemWeb.Tests/Castle.Facilities.AspNet.SystemWeb.Tests.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Castle.Facilities.AspNet.WebApi.Tests/Castle.Facilities.AspNet.WebApi.Tests.csproj b/src/Castle.Facilities.AspNet.WebApi.Tests/Castle.Facilities.AspNet.WebApi.Tests.csproj index 5fb8a66db9..44976c2b25 100644 --- a/src/Castle.Facilities.AspNet.WebApi.Tests/Castle.Facilities.AspNet.WebApi.Tests.csproj +++ b/src/Castle.Facilities.AspNet.WebApi.Tests/Castle.Facilities.AspNet.WebApi.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/Castle.Facilities.WcfIntegration.Demo/Castle.Facilities.WcfIntegration.Demo.csproj b/src/Castle.Facilities.WcfIntegration.Demo/Castle.Facilities.WcfIntegration.Demo.csproj index 93dea85510..d011c06161 100644 --- a/src/Castle.Facilities.WcfIntegration.Demo/Castle.Facilities.WcfIntegration.Demo.csproj +++ b/src/Castle.Facilities.WcfIntegration.Demo/Castle.Facilities.WcfIntegration.Demo.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/src/Castle.Facilities.WcfIntegration.Tests/Castle.Facilities.WcfIntegration.Tests.csproj b/src/Castle.Facilities.WcfIntegration.Tests/Castle.Facilities.WcfIntegration.Tests.csproj index a93e168526..a14b495793 100644 --- a/src/Castle.Facilities.WcfIntegration.Tests/Castle.Facilities.WcfIntegration.Tests.csproj +++ b/src/Castle.Facilities.WcfIntegration.Tests/Castle.Facilities.WcfIntegration.Tests.csproj @@ -12,8 +12,8 @@ - - + + diff --git a/src/Castle.Facilities.WcfIntegration/Client/Discovery/DiscoveryProxyCache.cs b/src/Castle.Facilities.WcfIntegration/Client/Discovery/DiscoveryProxyCache.cs index a9df98eda9..ff8c739d89 100644 --- a/src/Castle.Facilities.WcfIntegration/Client/Discovery/DiscoveryProxyCache.cs +++ b/src/Castle.Facilities.WcfIntegration/Client/Discovery/DiscoveryProxyCache.cs @@ -16,7 +16,8 @@ namespace Castle.Facilities.WcfIntegration { using System; using System.ServiceModel.Discovery; - using Castle.Core.Internal; + + using Castle.MicroKernel.Internal; public class DiscoveryProxyCache : DiscoveryEndpointProvider, IDisposable { diff --git a/src/Castle.Facilities.WcfIntegration/Client/Proxy/WcfChannelHolder.cs b/src/Castle.Facilities.WcfIntegration/Client/Proxy/WcfChannelHolder.cs index 1ae469d792..e69b346951 100644 --- a/src/Castle.Facilities.WcfIntegration/Client/Proxy/WcfChannelHolder.cs +++ b/src/Castle.Facilities.WcfIntegration/Client/Proxy/WcfChannelHolder.cs @@ -22,8 +22,9 @@ namespace Castle.Facilities.WcfIntegration using System.ServiceModel; using System.ServiceModel.Channels; using System.Threading; - using Castle.Core.Internal; + using Castle.Facilities.WcfIntegration.Internal; + using Castle.MicroKernel.Internal; public class WcfChannelHolder : IWcfChannelHolder { diff --git a/src/Castle.Facilities.WcfIntegration/Service/Discovery/LoadBalance/ListBasedLoadBalancePolicy.cs b/src/Castle.Facilities.WcfIntegration/Service/Discovery/LoadBalance/ListBasedLoadBalancePolicy.cs index 51a305e71f..171fc7dbf9 100644 --- a/src/Castle.Facilities.WcfIntegration/Service/Discovery/LoadBalance/ListBasedLoadBalancePolicy.cs +++ b/src/Castle.Facilities.WcfIntegration/Service/Discovery/LoadBalance/ListBasedLoadBalancePolicy.cs @@ -17,7 +17,8 @@ namespace Castle.Facilities.WcfIntegration using System; using System.Collections.Generic; using System.ServiceModel.Discovery; - using Castle.Core.Internal; + + using Castle.MicroKernel.Internal; public delegate bool PolicyMembership(EndpointDiscoveryMetadata endpoint); diff --git a/src/Castle.Facilities.WcfIntegration/Service/Discovery/ServiceCatalog/InMemoryServiceCatalog.cs b/src/Castle.Facilities.WcfIntegration/Service/Discovery/ServiceCatalog/InMemoryServiceCatalog.cs index 946f499099..94318d7e68 100644 --- a/src/Castle.Facilities.WcfIntegration/Service/Discovery/ServiceCatalog/InMemoryServiceCatalog.cs +++ b/src/Castle.Facilities.WcfIntegration/Service/Discovery/ServiceCatalog/InMemoryServiceCatalog.cs @@ -14,16 +14,16 @@ namespace Castle.Facilities.WcfIntegration { + using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.ServiceModel.Discovery; using Castle.Core; - using Castle.Core.Internal; - using System; + using Castle.MicroKernel.Internal; - public class InMemoryServiceCatalog : IServiceCatalogImplementation + public class InMemoryServiceCatalog : IServiceCatalogImplementation { private readonly List policies; private readonly ILoadBalancePolicyFactory policyFactory; diff --git a/src/Castle.Windsor.Tests/Castle.Windsor.Tests.csproj b/src/Castle.Windsor.Tests/Castle.Windsor.Tests.csproj index fd144919ff..4acb4e4e27 100644 --- a/src/Castle.Windsor.Tests/Castle.Windsor.Tests.csproj +++ b/src/Castle.Windsor.Tests/Castle.Windsor.Tests.csproj @@ -50,9 +50,9 @@ - - - + + + diff --git a/src/Castle.Windsor.Tests/MicroKernel/Internal/SlimReadWriteLockTestCase.cs b/src/Castle.Windsor.Tests/MicroKernel/Internal/SlimReadWriteLockTestCase.cs new file mode 100644 index 0000000000..0b8ea107cb --- /dev/null +++ b/src/Castle.Windsor.Tests/MicroKernel/Internal/SlimReadWriteLockTestCase.cs @@ -0,0 +1,187 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace CastleTests.MicroKernel.Internal +{ + using System.Threading; + + using Castle.MicroKernel.Internal; + + using NUnit.Framework; + + [TestFixture] + public class SlimReadWriteLockTestCase + { + private SlimReadWriteLock @lock; + + [SetUp] + public void SetUp() + { + @lock = new SlimReadWriteLock(); + } + + [Test] + public void Can_be_used_ForReading_multiple_nested_time() + { + using (@lock.ForReading()) + { + using (@lock.ForReading()) + { + Assert.IsTrue(@lock.IsReadLockHeld); + } + Assert.IsTrue(@lock.IsReadLockHeld); + } + } + + [Test] + public void Can_be_used_ForWriting_multiple_nested_time() + { + using (@lock.ForWriting()) + { + using (@lock.ForWriting()) + { + Assert.IsTrue(@lock.IsWriteLockHeld); + } + Assert.IsTrue(@lock.IsWriteLockHeld); + } + } + + [Test] + public void Can_be_used_ForReadingUpgradeable_multiple_nested_time() + { + using (@lock.ForReadingUpgradeable()) + { + using (@lock.ForReadingUpgradeable()) + { + Assert.IsTrue(@lock.IsUpgradeableReadLockHeld); + } + Assert.IsTrue(@lock.IsUpgradeableReadLockHeld); + } + } + + [Test] + public void Can_be_upgraded_from_nested_ForReadingUpgradeable() + { + using (@lock.ForReadingUpgradeable()) + { + using (var holder = @lock.ForReadingUpgradeable()) + { + holder.Upgrade(); + Assert.IsTrue(@lock.IsWriteLockHeld); + } + } + } + + [Test] + public void Can_be_used_ForReading_when_used_ForWriting() + { + using (@lock.ForWriting()) + { + using (var holder = @lock.ForReading()) + { + Assert.IsTrue(@lock.IsWriteLockHeld); + Assert.IsTrue(holder.LockAcquired); + } + } + } + + [Test] + public void Can_be_used_ForReading_when_used_ForReadingUpgradeable() + { + using (@lock.ForReadingUpgradeable()) + { + using (var holder = @lock.ForReading()) + { + Assert.IsTrue(@lock.IsUpgradeableReadLockHeld); + Assert.IsTrue(holder.LockAcquired); + } + } + } + + [Test] + public void Can_NOT_be_used_ForReadingUpgradeable_when_used_ForReading() + { + using (@lock.ForReading()) + { + Assert.Throws(typeof(LockRecursionException), () => @lock.ForReadingUpgradeable()); + } + } + + [Test] + public void Can_be_used_ForReadingUpgradeable_when_used_ForWriting() + { + using (@lock.ForWriting()) + { + using (var holder = @lock.ForReadingUpgradeable()) + { + Assert.IsTrue(@lock.IsWriteLockHeld); + Assert.IsTrue(holder.LockAcquired); + } + } + } + + [Test] + public void Can_NOT_be_used_ForWriting_when_used_ForReading() + { + using (@lock.ForReading()) + { + Assert.Throws(typeof(LockRecursionException), () => @lock.ForWriting()); + } + } + + [Test] + public void Can_be_used_ForWriting_when_used_ForReadingUpgradeable() + { + using (@lock.ForReadingUpgradeable()) + { + using (var holder = @lock.ForWriting()) + { + Assert.IsTrue(@lock.IsUpgradeableReadLockHeld); + Assert.IsTrue(holder.LockAcquired); + } + Assert.IsTrue(@lock.IsUpgradeableReadLockHeld); + } + } + + [Test] + public void Can_be_used_ForWriting_when_used_ForReadingUpgradeable_and_upgraded_after() + { + using (var upg = @lock.ForReadingUpgradeable()) + { + using (var holder = @lock.ForWriting()) + { + Assert.IsTrue(@lock.IsUpgradeableReadLockHeld); + Assert.IsTrue(holder.LockAcquired); + upg.Upgrade(); + } + Assert.IsTrue(@lock.IsUpgradeableReadLockHeld); + } + } + + [Test] + public void Can_be_used_ForWriting_when_used_ForReadingUpgradeable_and_upgraded_before() + { + using (var upg = @lock.ForReadingUpgradeable()) + { + upg.Upgrade(); + using (var holder = @lock.ForWriting()) + { + Assert.IsTrue(@lock.IsUpgradeableReadLockHeld); + Assert.IsTrue(holder.LockAcquired); + } + Assert.IsTrue(@lock.IsUpgradeableReadLockHeld); + } + } + } +} \ No newline at end of file diff --git a/src/Castle.Windsor/Castle.Windsor.csproj b/src/Castle.Windsor/Castle.Windsor.csproj index 401f95a1e4..19d524e178 100644 --- a/src/Castle.Windsor/Castle.Windsor.csproj +++ b/src/Castle.Windsor/Castle.Windsor.csproj @@ -24,7 +24,7 @@ - + diff --git a/src/Castle.Windsor/Core/Internal/SimpleThreadSafeCollection.cs b/src/Castle.Windsor/Core/Internal/SimpleThreadSafeCollection.cs index b0e8db0c40..470726f50b 100644 --- a/src/Castle.Windsor/Core/Internal/SimpleThreadSafeCollection.cs +++ b/src/Castle.Windsor/Core/Internal/SimpleThreadSafeCollection.cs @@ -16,7 +16,7 @@ namespace Castle.Core.Internal public class SimpleThreadSafeCollection { private readonly List implementation = new List(); - private readonly Lock @lock = Lock.Create(); + private readonly MicroKernel.Internal.Lock @lock =MicroKernel.Internal.Lock.Create(); public int Count { diff --git a/src/Castle.Windsor/Core/Internal/SimpleThreadSafeDictionary.cs b/src/Castle.Windsor/Core/Internal/SimpleThreadSafeDictionary.cs index 6aff34662f..6d159bbb7a 100644 --- a/src/Castle.Windsor/Core/Internal/SimpleThreadSafeDictionary.cs +++ b/src/Castle.Windsor/Core/Internal/SimpleThreadSafeDictionary.cs @@ -17,7 +17,7 @@ namespace Castle.Core.Internal using System; using System.Collections.Generic; using System.Linq; - + /// /// Simple type for thread safe adding/reading to/from keyed store. The difference between this and built in concurrent dictionary is that in this case adding is happening under a lock so never more than one thread will be adding at a time. /// @@ -26,7 +26,7 @@ namespace Castle.Core.Internal public class SimpleThreadSafeDictionary { private readonly Dictionary inner = new Dictionary(); - private readonly Lock @lock = Lock.Create(); + private readonly MicroKernel.Internal.Lock @lock = MicroKernel.Internal.Lock.Create(); public bool Contains(TKey key) { diff --git a/src/Castle.Windsor/Core/Internal/SimpleThreadSafeSet.cs b/src/Castle.Windsor/Core/Internal/SimpleThreadSafeSet.cs index 36568cd76f..c125a02e06 100644 --- a/src/Castle.Windsor/Core/Internal/SimpleThreadSafeSet.cs +++ b/src/Castle.Windsor/Core/Internal/SimpleThreadSafeSet.cs @@ -15,11 +15,11 @@ namespace Castle.Core.Internal { using System.Collections.Generic; - + public class SimpleThreadSafeSet { private readonly HashSet implementation = new HashSet(); - private readonly Lock @lock = Lock.Create(); + private readonly MicroKernel.Internal.Lock @lock = MicroKernel.Internal.Lock.Create(); public int Count { diff --git a/src/Castle.Windsor/MicroKernel/Internal/ILockHolder.cs b/src/Castle.Windsor/MicroKernel/Internal/ILockHolder.cs new file mode 100644 index 0000000000..392128bd70 --- /dev/null +++ b/src/Castle.Windsor/MicroKernel/Internal/ILockHolder.cs @@ -0,0 +1,23 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.MicroKernel.Internal +{ + using System; + + public interface ILockHolder : IDisposable + { + bool LockAcquired { get; } + } +} \ No newline at end of file diff --git a/src/Castle.Windsor/MicroKernel/Internal/IUpgradeableLockHolder.cs b/src/Castle.Windsor/MicroKernel/Internal/IUpgradeableLockHolder.cs new file mode 100644 index 0000000000..8080378eb1 --- /dev/null +++ b/src/Castle.Windsor/MicroKernel/Internal/IUpgradeableLockHolder.cs @@ -0,0 +1,25 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.MicroKernel.Internal +{ + using System.ComponentModel; + + [EditorBrowsable(EditorBrowsableState.Never)] + public interface IUpgradeableLockHolder : ILockHolder + { + ILockHolder Upgrade(); + ILockHolder Upgrade(bool waitForLock); + } +} \ No newline at end of file diff --git a/src/Castle.Windsor/MicroKernel/Internal/Lock.cs b/src/Castle.Windsor/MicroKernel/Internal/Lock.cs new file mode 100644 index 0000000000..d8fe62e3b7 --- /dev/null +++ b/src/Castle.Windsor/MicroKernel/Internal/Lock.cs @@ -0,0 +1,36 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.MicroKernel.Internal +{ + public abstract class Lock + { + public abstract IUpgradeableLockHolder ForReadingUpgradeable(); + public abstract ILockHolder ForReading(); + public abstract ILockHolder ForWriting(); + + public abstract IUpgradeableLockHolder ForReadingUpgradeable(bool waitForLock); + public abstract ILockHolder ForReading(bool waitForLock); + public abstract ILockHolder ForWriting(bool waitForLock); + + /// + /// Creates a new lock. + /// + /// + public static Lock Create() + { + return new SlimReadWriteLock(); + } + } +} diff --git a/src/Castle.Windsor/MicroKernel/Internal/NoOpLock.cs b/src/Castle.Windsor/MicroKernel/Internal/NoOpLock.cs new file mode 100644 index 0000000000..1742ea25b1 --- /dev/null +++ b/src/Castle.Windsor/MicroKernel/Internal/NoOpLock.cs @@ -0,0 +1,31 @@ +// Copyright 2004-2010 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.MicroKernel.Internal +{ + using System.ComponentModel; + + [EditorBrowsable(EditorBrowsableState.Never)] + internal class NoOpLock : ILockHolder + { + public static readonly ILockHolder Lock = new NoOpLock(); + + public void Dispose() + { + + } + + public bool LockAcquired => true; + } +} \ No newline at end of file diff --git a/src/Castle.Windsor/MicroKernel/Internal/SlimReadLockHolder.cs b/src/Castle.Windsor/MicroKernel/Internal/SlimReadLockHolder.cs new file mode 100644 index 0000000000..bd7161fb60 --- /dev/null +++ b/src/Castle.Windsor/MicroKernel/Internal/SlimReadLockHolder.cs @@ -0,0 +1,46 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.MicroKernel.Internal +{ + using System.ComponentModel; + using System.Threading; + + [EditorBrowsable(EditorBrowsableState.Never)] + internal class SlimReadLockHolder : ILockHolder + { + private readonly ReaderWriterLockSlim locker; + + public SlimReadLockHolder(ReaderWriterLockSlim locker, bool waitForLock) + { + this.locker = locker; + if(waitForLock) + { + locker.EnterReadLock(); + LockAcquired = true; + return; + } + LockAcquired = locker.TryEnterReadLock(0); + } + + public void Dispose() + { + if (!LockAcquired) return; + locker.ExitReadLock(); + LockAcquired = false; + } + + public bool LockAcquired { get; private set; } + } +} \ No newline at end of file diff --git a/src/Castle.Windsor/MicroKernel/Internal/SlimReadWriteLock.cs b/src/Castle.Windsor/MicroKernel/Internal/SlimReadWriteLock.cs new file mode 100644 index 0000000000..d1b630cbd3 --- /dev/null +++ b/src/Castle.Windsor/MicroKernel/Internal/SlimReadWriteLock.cs @@ -0,0 +1,64 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.MicroKernel.Internal +{ + using System.Threading; + + public class SlimReadWriteLock : Lock + { + private readonly ReaderWriterLockSlim locker = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); + + public override IUpgradeableLockHolder ForReadingUpgradeable() + { + return ForReadingUpgradeable(true); + } + + public override ILockHolder ForReading() + { + return ForReading(true); + } + + public override ILockHolder ForWriting() + { + return ForWriting(true); + } + + public override IUpgradeableLockHolder ForReadingUpgradeable(bool waitForLock) + { + return new SlimUpgradeableReadLockHolder(locker, waitForLock, locker.IsUpgradeableReadLockHeld || locker.IsWriteLockHeld); + } + + public override ILockHolder ForReading(bool waitForLock) + { + if (locker.IsReadLockHeld || locker.IsUpgradeableReadLockHeld || locker.IsWriteLockHeld) + { + return NoOpLock.Lock; + } + + return new SlimReadLockHolder(locker, waitForLock); + } + + public override ILockHolder ForWriting(bool waitForLock) + { + return locker.IsWriteLockHeld ? NoOpLock.Lock : new SlimWriteLockHolder(locker, waitForLock); + } + + public bool IsReadLockHeld => locker.IsReadLockHeld; + + public bool IsUpgradeableReadLockHeld => locker.IsUpgradeableReadLockHeld; + + public bool IsWriteLockHeld => locker.IsWriteLockHeld; + } +} \ No newline at end of file diff --git a/src/Castle.Windsor/MicroKernel/Internal/SlimUpgradeableReadLockHolder.cs b/src/Castle.Windsor/MicroKernel/Internal/SlimUpgradeableReadLockHolder.cs new file mode 100644 index 0000000000..cf405d1d9d --- /dev/null +++ b/src/Castle.Windsor/MicroKernel/Internal/SlimUpgradeableReadLockHolder.cs @@ -0,0 +1,79 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.MicroKernel.Internal +{ + using System.Threading; + + internal class SlimUpgradeableReadLockHolder : IUpgradeableLockHolder + { + private readonly ReaderWriterLockSlim locker; + private SlimWriteLockHolder writerLock; + private readonly bool wasLockAlreadySelf; + + public SlimUpgradeableReadLockHolder(ReaderWriterLockSlim locker, bool waitForLock, bool wasLockAlreadySelf) + { + this.locker = locker; + if (wasLockAlreadySelf) + { + LockAcquired = true; + this.wasLockAlreadySelf = true; + return; + } + + if(waitForLock) + { + locker.EnterUpgradeableReadLock(); + LockAcquired = true; + return; + } + + LockAcquired = locker.TryEnterUpgradeableReadLock(0); + } + + public void Dispose() + { + if (writerLock != null && writerLock.LockAcquired) + { + writerLock.Dispose(); + writerLock = null; + } + if (!LockAcquired) return; + if (!wasLockAlreadySelf) + { + locker.ExitUpgradeableReadLock(); + } + LockAcquired = false; + + } + + public ILockHolder Upgrade() + { + return Upgrade(true); + } + + public ILockHolder Upgrade(bool waitForLock) + { + if(locker.IsWriteLockHeld) + { + return NoOpLock.Lock; + } + + writerLock = new SlimWriteLockHolder(locker, waitForLock); + return writerLock; + } + + public bool LockAcquired { get; private set; } + } +} \ No newline at end of file diff --git a/src/Castle.Windsor/MicroKernel/Internal/SlimWriteLockHolder.cs b/src/Castle.Windsor/MicroKernel/Internal/SlimWriteLockHolder.cs new file mode 100644 index 0000000000..cd0295eb47 --- /dev/null +++ b/src/Castle.Windsor/MicroKernel/Internal/SlimWriteLockHolder.cs @@ -0,0 +1,46 @@ +// Copyright 2004-2009 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.MicroKernel.Internal +{ + using System.Threading; + + internal class SlimWriteLockHolder : ILockHolder + { + private readonly ReaderWriterLockSlim locker; + + private bool lockAcquired; + + public SlimWriteLockHolder(ReaderWriterLockSlim locker, bool waitForLock) + { + this.locker = locker; + if(waitForLock) + { + locker.EnterWriteLock(); + lockAcquired = true; + return; + } + lockAcquired = locker.TryEnterWriteLock(0); + } + + public void Dispose() + { + if(!LockAcquired) return; + locker.ExitWriteLock(); + lockAcquired = false; + } + + public bool LockAcquired => lockAcquired; + } +} \ No newline at end of file diff --git a/src/Castle.Windsor/MicroKernel/Lifestyle/Pool/DefaultPool.cs b/src/Castle.Windsor/MicroKernel/Lifestyle/Pool/DefaultPool.cs index 368f09ae25..83d0c8f060 100644 --- a/src/Castle.Windsor/MicroKernel/Lifestyle/Pool/DefaultPool.cs +++ b/src/Castle.Windsor/MicroKernel/Lifestyle/Pool/DefaultPool.cs @@ -18,9 +18,9 @@ namespace Castle.MicroKernel.Lifestyle.Pool using System.Collections.Generic; using Castle.Core; - using Castle.Core.Internal; using Castle.MicroKernel.Context; - + using Lock = Castle.MicroKernel.Internal.Lock; + [Serializable] public class DefaultPool : IPool, IDisposable { diff --git a/src/Castle.Windsor/MicroKernel/Lifestyle/Scoped/CallContextLifetimeScope.cs b/src/Castle.Windsor/MicroKernel/Lifestyle/Scoped/CallContextLifetimeScope.cs index 8c02b2421a..9fdf0db1ec 100644 --- a/src/Castle.Windsor/MicroKernel/Lifestyle/Scoped/CallContextLifetimeScope.cs +++ b/src/Castle.Windsor/MicroKernel/Lifestyle/Scoped/CallContextLifetimeScope.cs @@ -29,6 +29,8 @@ namespace Castle.MicroKernel.Lifestyle.Scoped using Castle.Core; using Castle.Core.Internal; + using Lock = Castle.MicroKernel.Internal.Lock; + /// /// Provides explicit lifetime scoping within logical path of execution. Used for types with . /// diff --git a/src/Castle.Windsor/MicroKernel/Releasers/LifecycledComponentsReleasePolicy.cs b/src/Castle.Windsor/MicroKernel/Releasers/LifecycledComponentsReleasePolicy.cs index e292044ef9..abc2fcbb56 100644 --- a/src/Castle.Windsor/MicroKernel/Releasers/LifecycledComponentsReleasePolicy.cs +++ b/src/Castle.Windsor/MicroKernel/Releasers/LifecycledComponentsReleasePolicy.cs @@ -27,6 +27,8 @@ namespace Castle.MicroKernel.Releasers using Castle.Core.Internal; using Castle.Windsor.Diagnostics; + using Lock = Castle.MicroKernel.Internal.Lock; + /// /// Tracks all components requiring decomission () /// diff --git a/src/Castle.Windsor/MicroKernel/SubSystems/Naming/DefaultNamingSubSystem.cs b/src/Castle.Windsor/MicroKernel/SubSystems/Naming/DefaultNamingSubSystem.cs index a64c58e7e7..5df98c30a2 100644 --- a/src/Castle.Windsor/MicroKernel/SubSystems/Naming/DefaultNamingSubSystem.cs +++ b/src/Castle.Windsor/MicroKernel/SubSystems/Naming/DefaultNamingSubSystem.cs @@ -22,6 +22,8 @@ namespace Castle.MicroKernel.SubSystems.Naming using Castle.Core.Internal; using Castle.MicroKernel.Util; + using Lock = Castle.MicroKernel.Internal.Lock; + [Serializable] public class DefaultNamingSubSystem : AbstractSubSystem, INamingSubSystem {