[suspend] Fix suspend race between mono-threads and sgen suspend when using the posix...
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 3 Nov 2015 00:19:56 +0000 (19:19 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 3 Nov 2015 00:19:56 +0000 (19:19 -0500)
The problem happens when a thread is left suspended by mono-threads and sgen tries to suspend it.

The signal mask of sigsuspend call in mono-threads didn't include sgen's suspend signal, making
it impossible for sgen to suspend it.

The fix is to include sgen's suspend signal into mono-threads sigsuspend mask. This way sgen
suspend can nest over mono-thread's.

The opposite is not needed as sgen never leaves threads suspended when it finishes and it holds
the suspend lock the whole time, making it impossible for mono-threads to initiate any suspend operation.

mono/utils/mono-threads-posix-signals.c

index 877eb6d00c11869b26bd6c6cd5ae39eeea680c52..ade08008827ad746753bbaa654bb7d5a47654ae5 100644 (file)
@@ -34,6 +34,9 @@ static int abort_signal_num;
 static sigset_t suspend_signal_mask;
 static sigset_t suspend_ack_signal_mask;
 
+//Can't avoid the circular dep on this. Will be gone pretty soon
+extern int mono_gc_get_suspend_signal (void);
+
 static int
 signal_search_alternative (int min_signal)
 {
@@ -261,6 +264,8 @@ mono_threads_posix_init_signals (MonoThreadPosixInitSignals signals)
 
                sigfillset (&suspend_signal_mask);
                sigdelset (&suspend_signal_mask, restart_signal_num);
+               if (!mono_thread_info_unified_management_enabled ())
+                       sigdelset (&suspend_signal_mask, mono_gc_get_suspend_signal ());
 
                sigemptyset (&suspend_ack_signal_mask);
                sigaddset (&suspend_ack_signal_mask, restart_signal_num);