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.
This commit is contained in:
Roland McGrath 1996-07-05 23:47:08 +00:00
parent 39d690795a
commit e33b438a84
2 changed files with 26 additions and 4 deletions

View File

@ -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)

View File

@ -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;
}