Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenric Müller <hemuller@microsoft.com>2016-07-06 17:28:58 +0300
committerHenric Müller <hemuller@microsoft.com>2016-07-07 09:56:16 +0300
commit3de4092e851144afac325ef1d2bfc98bcd73a24f (patch)
treeda44bad953f620ceec27c54ccc6f18e10d07f375
parentfdd84f680e7cbe00daa110dba1ef4b7232628000 (diff)
Fix for lock release in SynchronizationAttribute
* Making sure ownerThread is not nulled unless lockCount is zero. * Fixed so Locked property checks lockCount when determining if locked instead of _locked field which was never set. * Added test for setting Locked property. * Added test capturing the original issue.
-rw-r--r--mcs/class/corlib/System.Runtime.Remoting.Contexts/SynchronizationAttribute.cs20
-rw-r--r--mcs/class/corlib/Test/System.Runtime.Remoting.Contexts/SynchronizationAttributeTest.cs17
-rw-r--r--mcs/class/corlib/Test/System.Runtime.Remoting/SynchronizationAttributeTest.cs16
3 files changed, 40 insertions, 13 deletions
diff --git a/mcs/class/corlib/System.Runtime.Remoting.Contexts/SynchronizationAttribute.cs b/mcs/class/corlib/System.Runtime.Remoting.Contexts/SynchronizationAttribute.cs
index 7ef860da45f..49628abb344 100644
--- a/mcs/class/corlib/System.Runtime.Remoting.Contexts/SynchronizationAttribute.cs
+++ b/mcs/class/corlib/System.Runtime.Remoting.Contexts/SynchronizationAttribute.cs
@@ -47,8 +47,6 @@ namespace System.Runtime.Remoting.Contexts
int _flavor;
[NonSerialized]
- bool _locked;
- [NonSerialized]
int _lockCount;
[NonSerialized]
@@ -90,32 +88,26 @@ namespace System.Runtime.Remoting.Contexts
{
get
{
- return _locked;
+ return _lockCount > 0;
}
set
{
if (value)
{
- _mutex.WaitOne ();
+ AcquireLock ();
lock (this)
{
- _lockCount++;
if (_lockCount > 1)
ReleaseLock (); // Thread already had the lock
-
- _ownerThread = Thread.CurrentThread;
}
}
else
{
lock (this)
{
- while (_lockCount > 0 && _ownerThread == Thread.CurrentThread)
- {
- _lockCount--;
- _mutex.ReleaseMutex ();
- _ownerThread = null;
+ while (_lockCount > 0 && _ownerThread == Thread.CurrentThread) {
+ ReleaseLock ();
}
}
}
@@ -140,7 +132,9 @@ namespace System.Runtime.Remoting.Contexts
if (_lockCount > 0 && _ownerThread == Thread.CurrentThread) {
_lockCount--;
_mutex.ReleaseMutex ();
- _ownerThread = null;
+ if (_lockCount == 0) {
+ _ownerThread = null;
+ }
}
}
}
diff --git a/mcs/class/corlib/Test/System.Runtime.Remoting.Contexts/SynchronizationAttributeTest.cs b/mcs/class/corlib/Test/System.Runtime.Remoting.Contexts/SynchronizationAttributeTest.cs
index ba69ed0503b..a217969aefd 100644
--- a/mcs/class/corlib/Test/System.Runtime.Remoting.Contexts/SynchronizationAttributeTest.cs
+++ b/mcs/class/corlib/Test/System.Runtime.Remoting.Contexts/SynchronizationAttributeTest.cs
@@ -72,6 +72,23 @@ namespace MonoTests.System.Runtime.Remoting.Contexts {
}
[Test]
+ public void SetLocked()
+ {
+ SynchronizationAttribute sa = new SynchronizationAttribute(SynchronizationAttribute.REQUIRES_NEW);
+ sa.Locked = true;
+ Assert.IsTrue(sa.Locked, "Locked");
+ sa.Locked = false;
+ Assert.IsFalse(sa.Locked, "Locked");
+
+ sa.Locked = true;
+ Assert.IsTrue(sa.Locked, "Locked");
+ sa.Locked = true;
+ Assert.IsTrue(sa.Locked, "Locked");
+ sa.Locked = false;
+ Assert.IsFalse(sa.Locked, "Locked");
+ }
+
+ [Test]
public void SerializationRoundtrip ()
{
SynchronizationAttribute sa = new SynchronizationAttribute (SynchronizationAttribute.NOT_SUPPORTED, true);
diff --git a/mcs/class/corlib/Test/System.Runtime.Remoting/SynchronizationAttributeTest.cs b/mcs/class/corlib/Test/System.Runtime.Remoting/SynchronizationAttributeTest.cs
index 7596f3fd8bd..4005d1ad6c5 100644
--- a/mcs/class/corlib/Test/System.Runtime.Remoting/SynchronizationAttributeTest.cs
+++ b/mcs/class/corlib/Test/System.Runtime.Remoting/SynchronizationAttributeTest.cs
@@ -220,6 +220,7 @@ namespace MonoTests.System.Runtime.Remoting
public void TestLocked1 ()
{
sincob.Lock (false);
+
Thread tr = new Thread (new ThreadStart (FirstSyncThread));
tr.Start ();
Thread.Sleep (200);
@@ -331,6 +332,21 @@ namespace MonoTests.System.Runtime.Remoting
Assert.IsTrue (!otResult, "Concurrency detected in CallbackThread");
}
+ [Test]
+ public void TestSynchronizationReleasedOnMultipleAcquire ()
+ {
+
+ otResult = notreentrant.TestCallback ();
+
+ Thread tr = new Thread (new ThreadStart (CallbackThread));
+ tr.Start();
+
+ bool terminated = tr.Join(2000);
+ Assert.IsTrue(terminated, "Thread didn't get lock of context bound object.");
+
+ Assert.IsTrue (!otResult, "Concurrency detected in CallbackThread");
+ }
+
void CallbackThread ()
{
otResult = notreentrant.TestCallback ();