diff options
author | Roland McGrath <roland@gnu.org> | 1996-07-05 23:47:08 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 1996-07-05 23:47:08 +0000 |
commit | e33b438a8456aecf60a661ee75ac5977a7b49815 (patch) | |
tree | 4cb110b68bb4ddf7611aba3a5382561535c16d65 | |
parent | 39d690795a63d66c893ceecf74b910977cdfc8f1 (diff) | |
download | glibc-e33b438a8456aecf60a661ee75ac5977a7b49815.zip glibc-e33b438a8456aecf60a661ee75ac5977a7b49815.tar.gz glibc-e33b438a8456aecf60a661ee75ac5977a7b49815.tar.bz2 |
Fri Jul 5 12:22:51 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* hurd/hurdsig.c (_hurd_internal_post_signal): In case of handled
signal during critical section doing interruptible RPC, if
_hurdsig_abort_rpcs wants to change thread state, do thread_set_state
before thread_resume. If in critical section, pass 0 for SIGNO to
_hurdsig_abort_rpcs so rpc is interrupted regardless of SA_RESTART.
-rw-r--r-- | extra-lib.mk | 2 | ||||
-rw-r--r-- | hurd/hurdsig.c | 28 |
2 files changed, 26 insertions, 4 deletions
diff --git a/extra-lib.mk b/extra-lib.mk index 46eef03..e608894 100644 --- a/extra-lib.mk +++ b/extra-lib.mk @@ -25,7 +25,7 @@ alltypes-$(lib) := $(foreach o,$(object-suffixes-$(lib)),\ $(objpfx)$(patsubst %,$(libtype$o),\ $(lib:lib%=%))) -ifeq (,$(filter $(lib),extra-libs-others)) +ifeq (,$(filter $(lib),$(extra-libs-others))) lib-noranlib: $(alltypes-$(lib)) ifeq (yes,$(build-shared)) lib-noranlib: $(objpfx)$(lib).so$($(lib).so-version) diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c index a3ec24e..1da3fa5 100644 --- a/hurd/hurdsig.c +++ b/hurd/hurdsig.c @@ -802,19 +802,41 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss, } else { + int crit = __spin_lock_locked (&ss->critical_section_lock); + wait_for_reply - = (_hurdsig_abort_rpcs (ss, signo, 1, + = (_hurdsig_abort_rpcs (ss, + /* In a critical section, any RPC + should be cancelled instead of + restarted, regardless of + SA_RESTART, so the the entire + "atomic" operation can be aborted + as a unit. */ + crit ? 0 : signo, 1, &thread_state, &state_changed, &reply) != MACH_PORT_NULL); - if (__spin_lock_locked (&ss->critical_section_lock)) + if (crit) { /* The thread is in a critical section. Mark the signal as pending. When it finishes the critical section, it will check for pending signals. */ mark_pending (); - assert (! state_changed); + if (state_changed) + /* Some cases of interrupting an RPC must change the + thread state to back out the call. Normally this + change is rolled into the warping to the handler and + sigreturn, but we are not running the handler now + because the thread is in a critical section. Instead, + mutate the thread right away for the RPC interruption + and resume it; the RPC will return early so the + critical section can end soon. */ + __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR, + (natural_t *) &thread_state.basic, + MACHINE_THREAD_STATE_COUNT); + /* */ + ss->intr_port = MACH_PORT_NULL; __thread_resume (ss->thread); break; } |