From: Nicholas Nethercote Date: Wed, 18 May 2005 19:50:20 +0000 (+0000) Subject: Make VG_(wait_for_threadstate) local to linux/core_os.c. X-Git-Tag: svn/VALGRIND_3_0_0~548 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e1a1c6a0de0e8d3d5c8688a3e95fee9e9dfe11d3;p=thirdparty%2Fvalgrind.git Make VG_(wait_for_threadstate) local to linux/core_os.c. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3770 --- diff --git a/coregrind/core.h b/coregrind/core.h index d5093430ee..1081ea178c 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -408,9 +408,6 @@ extern Bool VG_(client_signal_OK)(Int sigNo); before using that signal to kill the process. */ extern void VG_(set_default_handler)(Int sig); -/* Wait until a thread-related predicate is true */ -extern void VG_(wait_for_threadstate)(Bool (*pred)(void *), void *arg); - /* --------------------------------------------------------------------- Exports of vg_mylibc.c ------------------------------------------------------------------ */ diff --git a/coregrind/linux/core_os.c b/coregrind/linux/core_os.c index d0cd7a7139..ef87b59743 100644 --- a/coregrind/linux/core_os.c +++ b/coregrind/linux/core_os.c @@ -118,10 +118,64 @@ static Bool alldead(void *v) //VG_(printf)("alldead: count=%d\n", c); return c <= 1; } + +static void sigvgchld_handler(Int sig) +{ + VG_(printf)("got a sigvgchld?\n"); +} + +/* + Wait until some predicate about threadstates is satisfied. + + This uses SIGVGCHLD as a notification that it is now worth + re-evaluating the predicate. + */ +static void wait_for_threadstate(Bool (*pred)(void *), void *arg) +{ + vki_sigset_t set, saved; + struct vki_sigaction sa, old_sa; + + /* + SIGVGCHLD is set to be ignored, and is unblocked by default. + This means all such signals are simply discarded. + + In this loop, we actually block it, and then poll for it with + sigtimedwait. + */ + VG_(sigemptyset)(&set); + VG_(sigaddset)(&set, VKI_SIGVGCHLD); + + VG_(set_sleeping)(VG_(master_tid), VgTs_Yielding); + VG_(sigprocmask)(VKI_SIG_BLOCK, &set, &saved); + + /* It shouldn't be necessary to set a handler, since the signal is + always blocked, but it seems to be necessary to convice the + kernel not to just toss the signal... */ + sa.ksa_handler = sigvgchld_handler; + sa.sa_flags = 0; + VG_(sigfillset)(&sa.sa_mask); + VG_(sigaction)(VKI_SIGVGCHLD, &sa, &old_sa); + + vg_assert(old_sa.ksa_handler == VKI_SIG_IGN); + + while(!(*pred)(arg)) { + struct vki_siginfo si; + Int ret = VG_(sigtimedwait)(&set, &si, NULL); + + if (ret > 0 && VG_(clo_trace_signals)) + VG_(message)(Vg_DebugMsg, "Got %d (code=%d) from tid lwp %d", + ret, si.si_code, si._sifields._kill._pid); + } + + VG_(sigaction)(VKI_SIGVGCHLD, &old_sa, NULL); + VG_(sigprocmask)(VKI_SIG_SETMASK, &saved, NULL); + VG_(set_running)(VG_(master_tid)); +} + void VGA_(reap_threads)(ThreadId self) { vg_assert(self == VG_(master_tid)); - VG_(wait_for_threadstate)(alldead, NULL); + wait_for_threadstate(alldead, NULL); } /* The we need to know the address of it so it can be diff --git a/coregrind/vg_signals.c b/coregrind/vg_signals.c index 02daeba992..2b806f0ca2 100644 --- a/coregrind/vg_signals.c +++ b/coregrind/vg_signals.c @@ -583,59 +583,6 @@ void do_sigprocmask_bitops ( Int vki_how, } } -static void sigvgchld_handler(Int sig) -{ - VG_(printf)("got a sigvgchld?\n"); -} - -/* - Wait until some predicate about threadstates is satisfied. - - This uses SIGVGCHLD as a notification that it is now worth - re-evaluating the predicate. - */ -void VG_(wait_for_threadstate)(Bool (*pred)(void *), void *arg) -{ - vki_sigset_t set, saved; - struct vki_sigaction sa, old_sa; - - /* - SIGVGCHLD is set to be ignored, and is unblocked by default. - This means all such signals are simply discarded. - - In this loop, we actually block it, and then poll for it with - sigtimedwait. - */ - VG_(sigemptyset)(&set); - VG_(sigaddset)(&set, VKI_SIGVGCHLD); - - VG_(set_sleeping)(VG_(master_tid), VgTs_Yielding); - VG_(sigprocmask)(VKI_SIG_BLOCK, &set, &saved); - - /* It shouldn't be necessary to set a handler, since the signal is - always blocked, but it seems to be necessary to convice the - kernel not to just toss the signal... */ - sa.ksa_handler = sigvgchld_handler; - sa.sa_flags = 0; - VG_(sigfillset)(&sa.sa_mask); - VG_(sigaction)(VKI_SIGVGCHLD, &sa, &old_sa); - - vg_assert(old_sa.ksa_handler == VKI_SIG_IGN); - - while(!(*pred)(arg)) { - struct vki_siginfo si; - Int ret = VG_(sigtimedwait)(&set, &si, NULL); - - if (ret > 0 && VG_(clo_trace_signals)) - VG_(message)(Vg_DebugMsg, "Got %d (code=%d) from tid lwp %d", - ret, si.si_code, si._sifields._kill._pid); - } - - VG_(sigaction)(VKI_SIGVGCHLD, &old_sa, NULL); - VG_(sigprocmask)(VKI_SIG_SETMASK, &saved, NULL); - VG_(set_running)(VG_(master_tid)); -} - /* This updates the thread's signal mask. There's no such thing as a process-wide signal mask.