X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libgc%2Fpthread_stop_world.c;h=68f1dce4306dbd5be23b66c688b45cc8320a766c;hb=c056798bb915fcf142ff4a4e15f9c7997e91001f;hp=60a63d5d8ac0b75b3dda3a158cd9ba2ca292d4ca;hpb=2a8259225695032220537b3c90a99d7a2686f214;p=mono.git diff --git a/libgc/pthread_stop_world.c b/libgc/pthread_stop_world.c index 60a63d5d8ac..68f1dce4306 100644 --- a/libgc/pthread_stop_world.c +++ b/libgc/pthread_stop_world.c @@ -163,6 +163,12 @@ static void _GC_suspend_handler(int sig) /* to accidentally leave a RESTART signal pending, thus causing us to */ /* continue prematurely in a future round. */ + /* Tell the thread that wants to start the world that this */ + /* thread has been started. Note that sem_post() is */ + /* the only async-signal-safe primitive in LinuxThreads. */ + sem_post(&GC_suspend_ack_sem); + + #if DEBUG_THREADS GC_printf1("Continuing 0x%lx\n", my_thread); #endif @@ -421,6 +427,7 @@ static void pthread_start_world() register GC_thread p; register int n_live_threads = 0; register int result; + int code; # if DEBUG_THREADS GC_printf0("World starting\n"); @@ -450,6 +457,20 @@ static void pthread_start_world() } } } + + #if DEBUG_THREADS + GC_printf0 ("All threads signaled"); + #endif + + for (i = 0; i < n_live_threads; i++) { + while (0 != (code = sem_wait(&GC_suspend_ack_sem))) { + if (errno != EINTR) { + GC_err_printf1("Sem_wait returned %ld\n", (unsigned long)code); + ABORT("sem_wait for handler failed"); + } + } + } + #if DEBUG_THREADS GC_printf0("World started\n"); #endif