mirror of
git://sourceware.org/git/glibc.git
synced 2025-03-06 20:58:33 +01:00
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:
parent
39d690795a
commit
e33b438a84
2 changed files with 26 additions and 4 deletions
|
@ -25,7 +25,7 @@ alltypes-$(lib) := $(foreach o,$(object-suffixes-$(lib)),\
|
||||||
$(objpfx)$(patsubst %,$(libtype$o),\
|
$(objpfx)$(patsubst %,$(libtype$o),\
|
||||||
$(lib:lib%=%)))
|
$(lib:lib%=%)))
|
||||||
|
|
||||||
ifeq (,$(filter $(lib),extra-libs-others))
|
ifeq (,$(filter $(lib),$(extra-libs-others)))
|
||||||
lib-noranlib: $(alltypes-$(lib))
|
lib-noranlib: $(alltypes-$(lib))
|
||||||
ifeq (yes,$(build-shared))
|
ifeq (yes,$(build-shared))
|
||||||
lib-noranlib: $(objpfx)$(lib).so$($(lib).so-version)
|
lib-noranlib: $(objpfx)$(lib).so$($(lib).so-version)
|
||||||
|
|
|
@ -802,19 +802,41 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int crit = __spin_lock_locked (&ss->critical_section_lock);
|
||||||
|
|
||||||
wait_for_reply
|
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,
|
&thread_state, &state_changed,
|
||||||
&reply)
|
&reply)
|
||||||
!= MACH_PORT_NULL);
|
!= MACH_PORT_NULL);
|
||||||
|
|
||||||
if (__spin_lock_locked (&ss->critical_section_lock))
|
if (crit)
|
||||||
{
|
{
|
||||||
/* The thread is in a critical section. Mark the signal as
|
/* The thread is in a critical section. Mark the signal as
|
||||||
pending. When it finishes the critical section, it will
|
pending. When it finishes the critical section, it will
|
||||||
check for pending signals. */
|
check for pending signals. */
|
||||||
mark_pending ();
|
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);
|
__thread_resume (ss->thread);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue