Created
March 29, 2012 20:40
-
-
Save kumpera/2243580 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/mono/metadata/sgen-os-posix.c b/mono/metadata/sgen-os-posix.c | |
index 5a1f53d..4005a3b 100644 | |
--- a/mono/metadata/sgen-os-posix.c | |
+++ b/mono/metadata/sgen-os-posix.c | |
@@ -51,6 +51,7 @@ static MonoSemType suspend_ack_semaphore; | |
static MonoSemType *suspend_ack_semaphore_ptr; | |
static sigset_t suspend_signal_mask; | |
+static sigset_t suspend_ack_signal_mask; | |
static void | |
suspend_thread (SgenThreadInfo *info, void *context) | |
@@ -104,6 +105,14 @@ suspend_thread (SgenThreadInfo *info, void *context) | |
mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, context); | |
DEBUG (4, fprintf (gc_debug_file, "Posting suspend_ack_semaphore for suspend from %p %p\n", info, (gpointer)mono_native_thread_id_get ())); | |
+ | |
+ /* | |
+ 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); | |
+ | |
/* notify the waiting thread */ | |
MONO_SEM_POST (suspend_ack_semaphore_ptr); | |
info->stop_count = stop_count; | |
@@ -114,6 +123,9 @@ suspend_thread (SgenThreadInfo *info, void *context) | |
sigsuspend (&suspend_signal_mask); | |
} while (info->signal != restart_signal_num && info->doing_handshake); | |
+ /* Unblock the restart signal. */ | |
+ pthread_sigmask (SIG_UNBLOCK, &suspend_ack_signal_mask, NULL); | |
+ | |
DEBUG (4, fprintf (gc_debug_file, "Posting suspend_ack_semaphore for resume from %p %p\n", info, (gpointer)mono_native_thread_id_get ())); | |
/* notify the waiting thread */ | |
MONO_SEM_POST (suspend_ack_semaphore_ptr); | |
@@ -145,6 +157,15 @@ restart_handler (int sig) | |
int old_errno = errno; | |
info = mono_thread_info_current (); | |
+ /* | |
+ If the thread info is null is means we're currently in the process of cleaning up, | |
+ the pthread destructor has already kicked in and it has explicitly invoked the suspend handler. | |
+ | |
+ This means this thread has been suspended, TLS is dead, so the only option we have is to | |
+ rely on pthread_self () and seatch over the thread list. | |
+ */ | |
+ if (!info) | |
+ info = mono_thread_info_lookup (pthread_self ()); | |
/* | |
* If a thread is dying there might be no thread info. In | |
@@ -254,6 +275,10 @@ mono_sgen_os_init (void) | |
sigfillset (&suspend_signal_mask); | |
sigdelset (&suspend_signal_mask, restart_signal_num); | |
+ | |
+ sigemptyset (&suspend_ack_signal_mask); | |
+ sigfillset (&suspend_signal_mask, restart_signal_num); | |
+ | |
} | |
int |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment