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:
authorLudovic Henry <luhenry@microsoft.com>2017-09-26 06:05:58 +0300
committerMarek Safar <marek.safar@gmail.com>2017-09-29 12:21:47 +0300
commit0dd35e9d6474922034489b23e6604c46605e119a (patch)
tree6ffe2703e53de487cf3fda666bd252287fa6d784
parent7ba4e9e7b16b1855a072093fad2db0abf96bf16a (diff)
[w32handle] Only own first handle if doing WaitHandle.WaitAny (#5625)mono-5.4.0.203
This is the behaviour on .NET, even if it goes against the documentation at https://msdn.microsoft.com/en-us/library/tdykks7z(v=vs.110).aspx#Anchor_2 Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=59281
-rw-r--r--mono/metadata/w32handle.c9
-rwxr-xr-xmono/tests/Makefile.am3
-rw-r--r--mono/tests/bug-59281.cs51
3 files changed, 60 insertions, 3 deletions
diff --git a/mono/metadata/w32handle.c b/mono/metadata/w32handle.c
index 3e53ad4f880..159c6a3672e 100644
--- a/mono/metadata/w32handle.c
+++ b/mono/metadata/w32handle.c
@@ -1297,8 +1297,13 @@ mono_w32handle_wait_multiple (gpointer *handles, gsize nhandles, gboolean waital
signalled = (waitall && count == nhandles) || (!waitall && count > 0);
if (signalled) {
- for (i = 0; i < nhandles; i++)
- own_if_signalled (handles [i], &abandoned [i]);
+ for (i = 0; i < nhandles; i++) {
+ if (own_if_signalled (handles [i], &abandoned [i]) && !waitall) {
+ /* if we are calling WaitHandle.WaitAny, .NET only owns the first one; it matters for Mutex which
+ * throw AbandonedMutexException in case we owned it but didn't release it */
+ break;
+ }
+ }
}
mono_w32handle_unlock_handles (handles, nhandles);
diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am
index a4bdf542740..47fa1563435 100755
--- a/mono/tests/Makefile.am
+++ b/mono/tests/Makefile.am
@@ -515,7 +515,8 @@ TESTS_CS_SRC= \
runtime-invoke.gen.cs \
imt_big_iface_test.cs \
bug-58782-plain-throw.cs \
- bug-58782-capture-and-throw.cs
+ bug-58782-capture-and-throw.cs \
+ bug-59281.cs
if AMD64
TESTS_CS_SRC += async-exc-compilation.cs finally_guard.cs finally_block_ending_in_dead_bb.cs
diff --git a/mono/tests/bug-59281.cs b/mono/tests/bug-59281.cs
new file mode 100644
index 00000000000..94250c277a7
--- /dev/null
+++ b/mono/tests/bug-59281.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Threading;
+
+class Driver
+{
+
+ static readonly Mutex[] mutexes = new Mutex[2];
+
+ public static void Main(string[] args)
+ {
+ for (int i = 0; i < mutexes.Length; i++) {
+ mutexes [i] = new Mutex();
+ }
+
+ Thread thread1 = new Thread(() => {
+ for (int i = 0; i < 1; i++) {
+ int idx = -1;
+ try {
+ idx = WaitHandle.WaitAny (mutexes);
+ Console.WriteLine($"Thread 1 iter: {i} with mutex: {idx}");
+ } finally {
+ if (idx != -1)
+ mutexes [idx].ReleaseMutex();
+ }
+ }
+
+ Console.WriteLine("Thread 1 ended");
+ });
+
+ thread1.Start();
+ thread1.Join();
+
+ Thread thread2 = new Thread(() => {
+ for (int i = 0; i < 1000; i++) {
+ int idx = -1;
+ try {
+ idx = WaitHandle.WaitAny (mutexes);
+ Console.WriteLine($"Thread 2 iter: {i} with mutex: {idx}");
+ } finally {
+ if (idx != -1)
+ mutexes [idx].ReleaseMutex();
+ }
+ }
+
+ Console.WriteLine("Thread 2 ended");
+ });
+
+ thread2.Start();
+ thread2.Join();
+ }
+} \ No newline at end of file