Add support for pthread_sigmask() and sigwait(). All absolutely
horrible, especially the latter.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@266 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h
index 765d719..d1cfca0 100644
--- a/coregrind/vg_include.h
+++ b/coregrind/vg_include.h
@@ -433,6 +433,8 @@
#define VG_USERREQ__PTHREAD_SETSPECIFIC 0x300F
#define VG_USERREQ__PTHREAD_GETSPECIFIC 0x3010
#define VG_USERREQ__READ_MILLISECOND_TIMER 0x3011
+#define VG_USERREQ__PTHREAD_SIGMASK 0x3012
+#define VG_USERREQ__SIGWAIT 0x3013
/* Cosmetic ... */
#define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101
@@ -478,6 +480,7 @@
VgTs_WaitFD, /* waiting for I/O completion on a fd */
VgTs_WaitMX, /* waiting on a mutex */
VgTs_WaitCV, /* waiting on a condition variable */
+ VgTs_WaitSIG, /* waiting due to sigwait() */
VgTs_Sleeping /* sleeping for a while */
}
ThreadStatus;
@@ -530,6 +533,19 @@
/* thread-specific data */
void* specifics[VG_N_THREAD_KEYS];
+ /* This thread's blocked-signals mask. Semantics is that for a
+ signal to be delivered to this thread, the signal must not be
+ blocked by either the process-wide signal mask nor by this
+ one. So, if this thread is prepared to handle any signal that
+ the process as a whole is prepared to handle, this mask should
+ be made empty -- and that it is its default, starting
+ state. */
+ vki_ksigset_t sig_mask;
+
+ /* When not VgTs_WaitSIG, has no meaning. When VgTs_WaitSIG,
+ is the set of signals for which we are sigwait()ing. */
+ vki_ksigset_t sigs_waited_for;
+
/* Stacks. When a thread slot is freed, we don't deallocate its
stack; we just leave it lying around for the next use of the
slot. If the next use of the slot requires a larger stack,
@@ -581,6 +597,9 @@
ThreadState;
+/* Trivial range check on tid. */
+extern Bool VG_(is_valid_tid) ( ThreadId tid );
+
/* Copy the specified thread's state into VG_(baseBlock) in
preparation for running it. */
extern void VG_(load_thread_state)( ThreadId );
@@ -591,6 +610,7 @@
/* Get the thread state block for the specified thread. */
extern ThreadState* VG_(get_thread_state)( ThreadId );
+extern ThreadState* VG_(get_thread_state_UNCHECKED)( ThreadId );
/* And for the currently running one, if valid. */
extern ThreadState* VG_(get_current_thread_state) ( void );
@@ -663,9 +683,10 @@
extern void VG_(sigstartup_actions) ( void );
-extern Bool VG_(deliver_signals) ( ThreadId );
+extern Bool VG_(deliver_signals) ( void );
extern void VG_(unblock_host_signal) ( Int sigNo );
-
+extern void VG_(notify_signal_machinery_of_thread_exit) ( ThreadId tid );
+extern void VG_(update_sigstate_following_WaitSIG_change) ( void );
/* Fake system calls for signal handling. */
extern void VG_(do__NR_sigaction) ( ThreadId tid );
@@ -797,9 +818,10 @@
definitions, which are different in places from those that glibc
defines. Since we're operating right at the kernel interface,
glibc's view of the world is entirely irrelevant. */
-extern Int VG_(ksigfillset)( vki_ksigset_t* set );
-extern Int VG_(ksigemptyset)( vki_ksigset_t* set );
-extern Int VG_(ksigaddset)( vki_ksigset_t* set, Int signum );
+extern Int VG_(ksigfillset)( vki_ksigset_t* set );
+extern Int VG_(ksigemptyset)( vki_ksigset_t* set );
+extern Bool VG_(kisemptysigset)( vki_ksigset_t* set );
+extern Int VG_(ksigaddset)( vki_ksigset_t* set, Int signum );
extern Int VG_(ksigprocmask)( Int how, const vki_ksigset_t* set,
vki_ksigset_t* oldset );
@@ -807,6 +829,11 @@
const vki_ksigaction* act,
vki_ksigaction* oldact );
extern Int VG_(ksigismember) ( vki_ksigset_t* set, Int signum );
+extern void VG_(ksigaddset_from_set)( vki_ksigset_t* dst,
+ vki_ksigset_t* src );
+extern void VG_(ksigdelset_from_set)( vki_ksigset_t* dst,
+ vki_ksigset_t* src );
+
extern Int VG_(ksignal)(Int signum, void (*sighandler)(Int));