Merge pull request #2721 from ludovic-henry/fix-mono_ms_ticks
[mono.git] / mono / utils / mono-threads-posix-signals.c
index d6b638829288f996cf07e65b70dfa621133b97ec..8200b101913cc05c9e612c69a2077737a5a5ac85 100644 (file)
 
 #include "mono-threads.h"
 
-#if defined(USE_POSIX_BACKEND) || defined(USE_POSIX_SYSCALL_ABORT)
+#if defined(USE_POSIX_BACKEND)
 
 #include <errno.h>
 #include <signal.h>
 
-#include "mono-semaphore.h"
 #include "mono-threads-posix-signals.h"
 
 #if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -34,8 +33,11 @@ static int abort_signal_num;
 static sigset_t suspend_signal_mask;
 static sigset_t suspend_ack_signal_mask;
 
-static int
-signal_search_alternative (int min_signal)
+//Can't avoid the circular dep on this. Will be gone pretty soon
+extern int mono_gc_get_suspend_signal (void);
+
+int
+mono_threads_posix_signal_search_alternative (int min_signal)
 {
 #if !defined (SIGRTMIN)
        g_error ("signal search only works with RTMIN");
@@ -62,7 +64,7 @@ signal_add_handler (int signo, gpointer handler, int flags)
        struct sigaction previous_sa;
        int ret;
 
-       sa.sa_sigaction = handler;
+       sa.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
        sigfillset (&sa.sa_mask);
 
        sa.sa_flags = SA_SIGINFO | flags;
@@ -86,7 +88,7 @@ suspend_signal_get (void)
 #else
        static int suspend_signum = -1;
        if (suspend_signum == -1)
-               suspend_signum = signal_search_alternative (-1);
+               suspend_signum = mono_threads_posix_signal_search_alternative (-1);
        return suspend_signum;
 #endif /* SIGRTMIN */
 }
@@ -105,7 +107,7 @@ restart_signal_get (void)
 #else
        static int resume_signum = -1;
        if (resume_signum == -1)
-               resume_signum = signal_search_alternative (suspend_signal_get () + 1);
+               resume_signum = mono_threads_posix_signal_search_alternative (suspend_signal_get () + 1);
        return resume_signum;
 #endif /* SIGRTMIN */
 }
@@ -125,7 +127,7 @@ abort_signal_get (void)
 #else
        static int abort_signum = -1;
        if (abort_signum == -1)
-               abort_signum = signal_search_alternative (restart_signal_get () + 1);
+               abort_signum = mono_threads_posix_signal_search_alternative (restart_signal_get () + 1);
        return abort_signum;
 #endif /* SIGRTMIN */
 }
@@ -178,13 +180,6 @@ suspend_signal_handler (int _dummy, siginfo_t *info, void *context)
        /* thread_state_init_from_sigctx return FALSE if the current thread is detaching and suspend can't continue. */
        current->suspend_can_continue = ret;
 
-       /*
-       Block the restart signal.
-       We need to block the restart signal while posting to the suspend_ack semaphore or we race to sigsuspend,
-       which might miss the signal and get stuck.
-       */
-       pthread_sigmask (SIG_BLOCK, &suspend_ack_signal_mask, NULL);
-
        /* This thread is doomed, all we can do is give up and let the suspender recover. */
        if (!ret) {
                THREADS_SUSPEND_DEBUG ("\tThread is dying, failed to capture state %p\n", current);
@@ -193,12 +188,16 @@ suspend_signal_handler (int _dummy, siginfo_t *info, void *context)
                /* We're done suspending */
                mono_threads_notify_initiator_of_suspend (current);
 
-               /* Unblock the restart signal. */
-               pthread_sigmask (SIG_UNBLOCK, &suspend_ack_signal_mask, NULL);
-
                goto done;
        }
 
+       /*
+       Block the restart signal.
+       We need to block the restart signal while posting to the suspend_ack semaphore or we race to sigsuspend,
+       which might miss the signal and get stuck.
+       */
+       pthread_sigmask (SIG_BLOCK, &suspend_ack_signal_mask, NULL);
+
        /* We're done suspending */
        mono_threads_notify_initiator_of_suspend (current);
 
@@ -214,7 +213,8 @@ suspend_signal_handler (int _dummy, siginfo_t *info, void *context)
 #if MONO_ARCH_HAS_MONO_CONTEXT
                MonoContext tmp = current->thread_saved_state [ASYNC_SUSPEND_STATE_INDEX].ctx;
                mono_threads_get_runtime_callbacks ()->setup_async_callback (&tmp, current->async_target, current->user_data);
-               current->async_target = current->user_data = NULL;
+               current->user_data = NULL;
+               current->async_target = NULL;
                mono_monoctx_to_sigctx (&tmp, context);
 #else
                g_error ("The new interruption machinery requires a working mono-context");
@@ -261,6 +261,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);
@@ -307,4 +309,4 @@ mono_threads_posix_get_abort_signal (void)
        return abort_signal_num;
 }
 
-#endif /* defined(USE_POSIX_BACKEND) || defined(USE_POSIX_SYSCALL_ABORT) */
+#endif /* defined(USE_POSIX_BACKEND) */