Merge pull request #3294 from lambdageek/dev/fix-42625
authorAleksey Kliger (λgeek) <akliger@gmail.com>
Tue, 19 Jul 2016 16:42:42 +0000 (12:42 -0400)
committerGitHub <noreply@github.com>
Tue, 19 Jul 2016 16:42:42 +0000 (12:42 -0400)
[threadpool-ms] Switch to GC Safe mode in event_wait backends

mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mono/metadata/threadpool-ms-io-epoll.c
mono/metadata/threadpool-ms-io-kqueue.c
mono/metadata/threadpool-ms-io-poll.c

index 4b9d569b1ad941d860ff1c0f95482b1c823e2b2d..f9d5df5af7f79b443fbae348eb22fc7678915d45 100644 (file)
@@ -9,6 +9,7 @@ using System.Reflection;
 using System.Reflection.Emit;
 using System.Diagnostics;
 using System.Threading;
+using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.Linq;
 
@@ -311,6 +312,10 @@ public class Tests : TestsBase, ITest2
                        wait_one ();
                        return 0;
                }
+               if (args.Length >0 && args [0] == "threadpool-io") {
+                       threadpool_io ();
+                       return 0;
+               }
                breakpoints ();
                single_stepping ();
                arguments ();
@@ -1541,6 +1546,20 @@ public class Tests : TestsBase, ITest2
        public override string virtual_method () {
                return "V2";
        }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void threadpool_io () {
+               Task<int> t = Task.Run (async () => {
+                       var wc = new System.Net.WebClient ();
+                       string filename = System.IO.Path.GetTempFileName ();
+
+                       var dl = wc.DownloadFileTaskAsync ("http://www.mono-project.com/", filename);
+                       await dl;
+                       System.IO.File.Delete (filename);
+                       return 1;
+                       });
+               var n = t.Result;
+       }
 }
 
 class TypeLoadClass {
index c0af12cb38ac15d9f023d11cfffa62408e2fb559..6407b9eae71e8986a2a42418e148fc85996b3ab4 100644 (file)
@@ -4035,6 +4035,30 @@ public class DebuggerTests
                // Make sure we are still in the cctor
                Assert.AreEqual (".cctor", e.Thread.GetFrames ()[0].Location.Method.Name);
        }
+
+       [Test]
+       public void ThreadpoolIOsinglestep () {
+               // This is a regression test for #42625.
+               // It tests the interaction (particularly in coop GC of
+               // the threadpool I/O mechanism and the soft debugger.
+               Start (new string [] { "dtest-app.exe", "threadpool-io" });
+
+               Event e = run_until ("threadpool_io");
+               var req = create_step (e);
+               req.Enable ();
+
+               // step to start the task
+               e = step_once ();
+               
+               req.Disable ();
+
+               // run until completion of the test method
+               e = step_out ();
+
+               vm.Resume ();
+
+               vm.Suspend ();
+       }
 }
 
 }
index 462fa98df8143115552eeb48bc32c6e21813a529..2bc99e105b9cca5e57845d28d8ff21e3a68a305d 100644 (file)
@@ -84,7 +84,9 @@ epoll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), g
 
        mono_gc_set_skip_thread (TRUE);
 
+       MONO_ENTER_GC_SAFE;
        ready = epoll_wait (epoll_fd, epoll_events, EPOLL_NEVENTS, -1);
+       MONO_EXIT_GC_SAFE;
 
        mono_gc_set_skip_thread (FALSE);
 
index e162c3cc9be24eec2bc8dfe1558449bedb9ac314..4422b668e8f61c7c2d2a630e1b1cb702dfb5fd56 100644 (file)
@@ -81,7 +81,9 @@ kqueue_event_wait (void (*callback) (gint fd, gint events, gpointer user_data),
 
        mono_gc_set_skip_thread (TRUE);
 
+       MONO_ENTER_GC_SAFE;
        ready = kevent (kqueue_fd, NULL, 0, kqueue_events, KQUEUE_NEVENTS, NULL);
+       MONO_EXIT_GC_SAFE;
 
        mono_gc_set_skip_thread (FALSE);
 
index 4d4cceb090269f97b4f53ecad27601c128da93a6..68e6611fba2619ee83cb65ea78cf16c249549c37 100644 (file)
@@ -143,7 +143,9 @@ poll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gp
 
        mono_gc_set_skip_thread (TRUE);
 
+       MONO_ENTER_GC_SAFE;
        ready = mono_poll (poll_fds, poll_fds_size, -1);
+       MONO_EXIT_GC_SAFE;
 
        mono_gc_set_skip_thread (FALSE);