>From 71148c3e1ba19e1dd444191b617c987893997ce5 Mon Sep 17 00:00:00 2001 From: Jeremie Koenig Date: Sat, 4 Sep 2010 13:51:08 +0000 Subject: [PATCH 2/8] _hurd_internal_post_signal: Scope variables more restrictively * hurd/hurdsig.c (_hurd_internal_post_signal): Move the variable declarations into the first-level inner functions which actually use them. --- hurd/hurdsig.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/hurd/hurdsig.c b/hurd/hurdsig.c index c139805..0ea78e1 100644 --- a/hurd/hurdsig.c +++ b/hurd/hurdsig.c @@ -434,86 +434,82 @@ abort_all_rpcs (int signo, struct machine_thread_all_state *state, int live) switch (err) { case MACH_RCV_TIMED_OUT: case MACH_RCV_TOO_LARGE: break; default: assert_perror (err); } } } struct hurd_signal_preemptor *_hurdsig_preemptors = 0; sigset_t _hurdsig_preempted_set; /* XXX temporary to deal with spelling fix */ weak_alias (_hurdsig_preemptors, _hurdsig_preempters) /* Mask of stop signals. */ #define STOPSIGS (sigmask (SIGTTIN) | sigmask (SIGTTOU) | \ sigmask (SIGSTOP) | sigmask (SIGTSTP)) /* Deliver a signal. SS is not locked. */ void _hurd_internal_post_signal (struct hurd_sigstate *ss, int signo, struct hurd_signal_detail *detail, mach_port_t reply_port, mach_msg_type_name_t reply_port_type, int untraced) { - error_t err; - struct machine_thread_all_state thread_state; - enum { stop, ignore, core, term, handle } act; - sighandler_t handler; - sigset_t pending; - int ss_suspended; - /* Reply to this sig_post message. */ __typeof (__msg_sig_post_reply) *reply_rpc = (untraced ? __msg_sig_post_untraced_reply : __msg_sig_post_reply); void reply (void) { error_t err; if (reply_port == MACH_PORT_NULL) return; err = (*reply_rpc) (reply_port, reply_port_type, 0); reply_port = MACH_PORT_NULL; if (err != MACH_SEND_INVALID_DEST) /* Ignore dead reply port. */ assert_perror (err); } /* Actual delivery of a single signal. Called with SS unlocked. When the signal is delivered, return 1 with SS locked. If the signal is being traced, return 0 with SS unlocked. */ int post_signal (void) { + struct machine_thread_all_state thread_state; + enum { stop, ignore, core, term, handle } act; + int ss_suspended; /* Mark the signal as pending. */ void mark_pending (void) { __sigaddset (&ss->pending, signo); /* Save the details to be given to the handler when SIGNO is unblocked. */ ss->pending_data[signo] = *detail; } /* Suspend the process with SIGNO. */ void suspend (void) { /* Stop all other threads and mark ourselves stopped. */ __USEPORT (PROC, ({ /* Hold the siglock while stopping other threads to be sure it is not held by another thread afterwards. */ __mutex_lock (&_hurd_siglock); __proc_dostop (port, _hurd_msgport_thread); __mutex_unlock (&_hurd_siglock); abort_all_rpcs (signo, &thread_state, 1); reply (); __proc_mark_stop (port, signo, detail->code); })); _hurd_stopped = 1; } /* Resume the process after a suspension. */ void resume (void) { @@ -524,60 +520,63 @@ int post_signal (void) if (! _hurd_stopped) return; /* Tell the proc server we are continuing. */ __USEPORT (PROC, __proc_mark_cont (port)); /* Fetch ports to all our threads and resume them. */ err = __task_threads (__mach_task_self (), &threads, &nthreads); assert_perror (err); for (i = 0; i < nthreads; ++i) { if (threads[i] != _hurd_msgport_thread && (act != handle || threads[i] != ss->thread)) { err = __thread_resume (threads[i]); assert_perror (err); } err = __mach_port_deallocate (__mach_task_self (), threads[i]); assert_perror (err); } __vm_deallocate (__mach_task_self (), (vm_address_t) threads, nthreads * sizeof *threads); _hurd_stopped = 0; if (act == handle) /* The thread that will run the handler is already suspended. */ ss_suspended = 1; } + error_t err; + sighandler_t handler; + if (signo == 0) { if (untraced) /* This is PTRACE_CONTINUE. */ resume (); /* This call is just to check for pending signals. */ __spin_lock (&ss->lock); return 1; } thread_state.set = 0; /* We know nothing. */ __spin_lock (&ss->lock); /* Check for a preempted signal. Preempted signals can arrive during critical sections. */ { inline sighandler_t try_preemptor (struct hurd_signal_preemptor *pe) { /* PE cannot be null. */ do { if (HURD_PREEMPT_SIGNAL_P (pe, signo, detail->code)) { if (pe->preemptor) { sighandler_t handler = (*pe->preemptor) (pe, ss, &signo, detail); if (handler != SIG_ERR) return handler; @@ -948,60 +947,62 @@ int post_signal (void) /* Reset to SIG_DFL if requested. SIGILL and SIGTRAP cannot be automatically reset when delivered; the system silently enforces this restriction. */ if (ss->actions[signo].sa_flags & SA_RESETHAND && signo != SIGILL && signo != SIGTRAP) ss->actions[signo].sa_handler = SIG_DFL; /* Start the thread running the handler (or possibly waiting for an RPC reply before running the handler). */ err = __thread_set_state (ss->thread, MACHINE_THREAD_STATE_FLAVOR, (natural_t *) &thread_state.basic, MACHINE_THREAD_STATE_COUNT); assert_perror (err); err = __thread_resume (ss->thread); assert_perror (err); thread_state.set = 0; /* Everything we know is now wrong. */ break; } } return 1; } /* Try to find a non-blocked pending signal and deliver it. Called with SS locked. If a signal is delivered, return 1 and leave SS locked. If the signal is traced, or if none can be found, return 0 with SS unlocked. */ int check_pending_signal (void) { + sigset_t pending; + /* Return nonzero if SS has any signals pending we should worry about. We don't worry about any pending signals if we are stopped, nor if SS is in a critical section. We are guaranteed to get a sig_post message before any of them become deliverable: either the SIGCONT signal, or a sig_post with SIGNO==0 as an explicit poll when the thread finishes its critical section. */ inline int signals_pending (void) { if (_hurd_stopped || __spin_lock_locked (&ss->critical_section_lock)) return 0; return pending = ss->pending & ~ss->blocked; } untraced = 0; if (signals_pending ()) { for (signo = 1; signo < NSIG; ++signo) if (__sigismember (&pending, signo)) { deliver_pending: __sigdelset (&ss->pending, signo); *detail = ss->pending_data[signo]; __spin_unlock (&ss->lock); return post_signal (); } } /* No pending signals left undelivered for this thread. -- 1.7.2.3