summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1994-10-07 19:27:59 +0000
committerRoland McGrath <roland@gnu.org>1994-10-07 19:27:59 +0000
commitfb4192123b52ed3ab265166f6553b09d81d4d91e (patch)
treef674910b7209a6a58ec71660cdb26d303c4db33c
parent5f8c92c66eb80ef5f5c1c5345144c0d32cab24da (diff)
(abort_rpcs): Return the reply port or null, instead of boolean.
(abort_all_rpcs): Record the returns from abort_rpcs and wait for a message on each reply port. Don't bother locking _hurd_siglock.
-rw-r--r--hurd/hurdsig.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c
index 1bae54ee80..c986d1e85a 100644
--- a/hurd/hurdsig.c
+++ b/hurd/hurdsig.c
@@ -252,11 +252,12 @@ interrupted_reply_port_location (struct machine_thread_all_state *thread_state)
This uses only the constant member SS->thread and the unlocked, atomically
set member SS->intr_port, so no locking is needed.
- Returns nonzero iff it successfully sent an interrupt_operation and
- therefore the thread should wait for its pending RPC to return (possibly
- EINTR) before taking the incoming signal. */
+If successfully sent an interrupt_operation and therefore the thread should
+ wait for its pending RPC to return (possibly EINTR) before taking the
+ incoming signal, returns the reply port to be received on. Otherwise
+ returns MACH_PORT_NULL. */
-static int
+static mach_port_t
abort_rpcs (struct hurd_sigstate *ss, int signo,
struct machine_thread_all_state *state,
mach_port_t *reply_port, mach_msg_type_name_t reply_port_type)
@@ -342,17 +343,28 @@ abort_rpcs (struct hurd_sigstate *ss, int signo,
static void
abort_all_rpcs (int signo, struct machine_thread_all_state *state)
{
- struct hurd_sigstate *ss;
-
/* We can just loop over the sigstates. Any thread doing something
- interruptible must have one. We needn't bother locking (see
- abort_rpcs). */
+ interruptible must have one. We needn't bother locking because all
+ other threads are stopped. */
- __mutex_lock (&_hurd_siglock);
for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
if (ss->thread != _hurd_msgport_thread)
- abort_rpcs (ss, signo, state, NULL, 0);
- __mutex_unlock (&_hurd_siglock);
+ /* Abort any operation in progress with interrupt_operation. We
+ record this by putting the reply port into SS->intr_port, or
+ MACH_PORT_NULL if no interruption was done. We will wait for
+ all the replies below. */
+ ss->intr_port = abort_rpcs (ss, signo, state, NULL, 0);
+
+ /* Wait for replies from all the successfully interrupted RPCs. */
+ for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
+ if (ss->intr_port != MACH_PORT_NULL)
+ {
+ error_t err;
+ mach_msg_header_t head;
+ err = __mach_msg (&head, MACH_RCV_MSG, 0, sizeof head, ss->intr_port,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ assert (err == KERN_SUCCESS || err == MACH_RCV_TOO_LARGE);
+ }
}
@@ -626,8 +638,9 @@ _hurd_internal_post_signal (struct hurd_sigstate *ss,
/* Stop the thread and abort its pending RPC operations. */
if (! ss_suspended)
__thread_suspend (ss->thread);
- wait_for_reply = abort_rpcs (ss, signo, &thread_state,
- &reply_port, reply_port_type);
+ wait_for_reply = (abort_rpcs (ss, signo, &thread_state,
+ &reply_port, reply_port_type)
+ != MACH_PORT_NULL);
/* Call the machine-dependent function to set the thread up
to run the signal handler, and preserve its old context. */