Tweak the in-kernel API for sending signals to threads:

- Rename tdsignal() to tdsendsignal() and make it private to kern_sig.c.
- Add tdsignal() and tdksignal() routines that mirror psignal() and
  pksignal() except that they accept a thread as an argument instead of
  a process.  They send a signal to a specific thread rather than to an
  individual process.

Reviewed by:	kib
This commit is contained in:
John Baldwin 2010-06-29 20:41:52 +00:00
parent cfbcffa248
commit ad6eec7b9e
6 changed files with 41 additions and 22 deletions

@ -501,7 +501,7 @@ linux_rt_sigtimedwait(struct thread *td,
/* Repost if we got an error. */ /* Repost if we got an error. */
if (error && info.ksi_signo) { if (error && info.ksi_signo) {
PROC_LOCK(td->td_proc); PROC_LOCK(td->td_proc);
tdsignal(td->td_proc, td, info.ksi_signo, &info); tdksignal(td, info.ksi_signo, &info);
PROC_UNLOCK(td->td_proc); PROC_UNLOCK(td->td_proc);
} else } else
td->td_retval[0] = info.ksi_signo; td->td_retval[0] = info.ksi_signo;
@ -587,7 +587,7 @@ linux_do_tkill(struct thread *td, l_int tgid, l_int pid, l_int signum)
ksi.ksi_pid = proc->p_pid; ksi.ksi_pid = proc->p_pid;
ksi.ksi_uid = proc->p_ucred->cr_ruid; ksi.ksi_uid = proc->p_ucred->cr_ruid;
error = tdsignal(p, NULL, ksi.ksi_signo, &ksi); error = pksignal(p, ksi.ksi_signo, &ksi);
out: out:
PROC_UNLOCK(p); PROC_UNLOCK(p);

@ -755,13 +755,13 @@ interpret:
/* /*
* If tracing the process, trap to debugger so breakpoints * If tracing the process, trap to debugger so breakpoints
* can be set before the program executes. * can be set before the program executes.
* Use tdsignal to deliver signal to current thread, use * Use tdsignal to deliver signal to current thread, using
* psignal may cause the signal to be delivered to wrong thread * psignal may cause the signal to be delivered to wrong thread
* because that thread will exit, remember we are going to enter * because that thread will exit, remember we are going to enter
* single thread mode. * single thread mode.
*/ */
if (p->p_flag & P_TRACED) if (p->p_flag & P_TRACED)
tdsignal(p, td, SIGTRAP, NULL); tdsignal(td, SIGTRAP);
/* clear "fork but no exec" flag, as we _are_ execing */ /* clear "fork but no exec" flag, as we _are_ execing */
p->p_acflag &= ~AFORK; p->p_acflag &= ~AFORK;

@ -732,7 +732,7 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options,
p->p_oppid = 0; p->p_oppid = 0;
proc_reparent(p, t); proc_reparent(p, t);
PROC_UNLOCK(p); PROC_UNLOCK(p);
tdsignal(t, NULL, SIGCHLD, p->p_ksi); pksignal(t, SIGCHLD, p->p_ksi);
wakeup(t); wakeup(t);
cv_broadcast(&p->p_pwait); cv_broadcast(&p->p_pwait);
PROC_UNLOCK(t); PROC_UNLOCK(t);

@ -107,6 +107,8 @@ static int killpg1(struct thread *td, int sig, int pgid, int all,
ksiginfo_t *ksi); ksiginfo_t *ksi);
static int issignal(struct thread *td, int stop_allowed); static int issignal(struct thread *td, int stop_allowed);
static int sigprop(int sig); static int sigprop(int sig);
static int tdsendsignal(struct proc *p, struct thread *td, int sig,
ksiginfo_t *ksi);
static void tdsigwakeup(struct thread *, int, sig_t, int); static void tdsigwakeup(struct thread *, int, sig_t, int);
static void sig_suspend_threads(struct thread *, struct proc *, int); static void sig_suspend_threads(struct thread *, struct proc *, int);
static int filt_sigattach(struct knote *kn); static int filt_sigattach(struct knote *kn);
@ -1797,7 +1799,7 @@ sigqueue(struct thread *td, struct sigqueue_args *uap)
ksi.ksi_pid = td->td_proc->p_pid; ksi.ksi_pid = td->td_proc->p_pid;
ksi.ksi_uid = td->td_ucred->cr_ruid; ksi.ksi_uid = td->td_ucred->cr_ruid;
ksi.ksi_value.sival_ptr = uap->value; ksi.ksi_value.sival_ptr = uap->value;
error = tdsignal(p, NULL, ksi.ksi_signo, &ksi); error = pksignal(p, ksi.ksi_signo, &ksi);
} }
PROC_UNLOCK(p); PROC_UNLOCK(p);
return (error); return (error);
@ -1907,7 +1909,7 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
mtx_unlock(&ps->ps_mtx); mtx_unlock(&ps->ps_mtx);
p->p_code = code; /* XXX for core dump/debugger */ p->p_code = code; /* XXX for core dump/debugger */
p->p_sig = sig; /* XXX to verify code */ p->p_sig = sig; /* XXX to verify code */
tdsignal(p, td, sig, ksi); tdsendsignal(p, td, sig, ksi);
} }
PROC_UNLOCK(p); PROC_UNLOCK(p);
} }
@ -1962,14 +1964,14 @@ psignal(struct proc *p, int sig)
ksiginfo_init(&ksi); ksiginfo_init(&ksi);
ksi.ksi_signo = sig; ksi.ksi_signo = sig;
ksi.ksi_code = SI_KERNEL; ksi.ksi_code = SI_KERNEL;
(void) tdsignal(p, NULL, sig, &ksi); (void) tdsendsignal(p, NULL, sig, &ksi);
} }
void int
pksignal(struct proc *p, int sig, ksiginfo_t *ksi) pksignal(struct proc *p, int sig, ksiginfo_t *ksi)
{ {
(void) tdsignal(p, NULL, sig, ksi); return (tdsendsignal(p, NULL, sig, ksi));
} }
int int
@ -1992,11 +1994,29 @@ psignal_event(struct proc *p, struct sigevent *sigev, ksiginfo_t *ksi)
if (td == NULL) if (td == NULL)
return (ESRCH); return (ESRCH);
} }
return (tdsignal(p, td, ksi->ksi_signo, ksi)); return (tdsendsignal(p, td, ksi->ksi_signo, ksi));
} }
int void
tdsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi) tdsignal(struct thread *td, int sig)
{
ksiginfo_t ksi;
ksiginfo_init(&ksi);
ksi.ksi_signo = sig;
ksi.ksi_code = SI_KERNEL;
(void) tdsendsignal(td->td_proc, td, sig, &ksi);
}
void
tdksignal(struct thread *td, int sig, ksiginfo_t *ksi)
{
(void) tdsendsignal(td->td_proc, td, sig, ksi);
}
static int
tdsendsignal(struct proc *p, struct thread *td, int sig, ksiginfo_t *ksi)
{ {
sig_t action; sig_t action;
sigqueue_t *sigqueue; sigqueue_t *sigqueue;
@ -2882,7 +2902,7 @@ sigparent(struct proc *p, int reason, int status)
if (KSI_ONQ(p->p_ksi)) if (KSI_ONQ(p->p_ksi))
return; return;
} }
tdsignal(p->p_pptr, NULL, SIGCHLD, p->p_ksi); pksignal(p->p_pptr, SIGCHLD, p->p_ksi);
} }
static void static void

@ -326,7 +326,7 @@ thr_kill(struct thread *td, struct thr_kill_args *uap)
error = 0; error = 0;
if (uap->sig == 0) if (uap->sig == 0)
break; break;
tdsignal(p, ttd, uap->sig, &ksi); tdksignal(ttd, uap->sig, &ksi);
} }
} }
} }
@ -342,7 +342,7 @@ thr_kill(struct thread *td, struct thr_kill_args *uap)
else if (!_SIG_VALID(uap->sig)) else if (!_SIG_VALID(uap->sig))
error = EINVAL; error = EINVAL;
else else
tdsignal(p, ttd, uap->sig, &ksi); tdksignal(ttd, uap->sig, &ksi);
} }
PROC_UNLOCK(p); PROC_UNLOCK(p);
return (error); return (error);
@ -384,8 +384,7 @@ thr_kill2(struct thread *td, struct thr_kill2_args *uap)
error = 0; error = 0;
if (uap->sig == 0) if (uap->sig == 0)
break; break;
tdsignal(p, ttd, uap->sig, tdksignal(ttd, uap->sig, &ksi);
&ksi);
} }
} }
} }
@ -401,7 +400,7 @@ thr_kill2(struct thread *td, struct thr_kill2_args *uap)
else if (!_SIG_VALID(uap->sig)) else if (!_SIG_VALID(uap->sig))
error = EINVAL; error = EINVAL;
else else
tdsignal(p, ttd, uap->sig, &ksi); tdksignal(ttd, uap->sig, &ksi);
} }
} }
PROC_UNLOCK(p); PROC_UNLOCK(p);

@ -330,7 +330,7 @@ int cursig(struct thread *td, int stop_allowed);
void execsigs(struct proc *p); void execsigs(struct proc *p);
void gsignal(int pgid, int sig, ksiginfo_t *ksi); void gsignal(int pgid, int sig, ksiginfo_t *ksi);
void killproc(struct proc *p, char *why); void killproc(struct proc *p, char *why);
void pksignal(struct proc *p, int sig, ksiginfo_t *ksi); int pksignal(struct proc *p, int sig, ksiginfo_t *ksi);
void pgsigio(struct sigio **, int signum, int checkctty); void pgsigio(struct sigio **, int signum, int checkctty);
void pgsignal(struct pgrp *pgrp, int sig, int checkctty, ksiginfo_t *ksi); void pgsignal(struct pgrp *pgrp, int sig, int checkctty, ksiginfo_t *ksi);
int postsig(int sig); int postsig(int sig);
@ -346,8 +346,8 @@ int sig_ffs(sigset_t *set);
void siginit(struct proc *p); void siginit(struct proc *p);
void signotify(struct thread *td); void signotify(struct thread *td);
void tdsigcleanup(struct thread *td); void tdsigcleanup(struct thread *td);
int tdsignal(struct proc *p, struct thread *td, int sig, void tdsignal(struct thread *td, int sig);
ksiginfo_t *ksi); void tdksignal(struct thread *td, int sig, ksiginfo_t *ksi);
void trapsignal(struct thread *td, ksiginfo_t *); void trapsignal(struct thread *td, ksiginfo_t *);
int ptracestop(struct thread *td, int sig); int ptracestop(struct thread *td, int sig);
ksiginfo_t * ksiginfo_alloc(int); ksiginfo_t * ksiginfo_alloc(int);