diff options
author | davidxu <davidxu@FreeBSD.org> | 2006-01-07 03:15:21 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2006-01-07 03:15:21 +0000 |
commit | a4e63b41b7f9faecf80e966fc616f39906f3b1a5 (patch) | |
tree | ce18940b36a4c7e6c9f25065e5a3fd4227b9badc | |
parent | 6ad90eb0a77b2fee9df4004d2400b9fcf43a1e7f (diff) | |
download | FreeBSD-src-a4e63b41b7f9faecf80e966fc616f39906f3b1a5.zip FreeBSD-src-a4e63b41b7f9faecf80e966fc616f39906f3b1a5.tar.gz |
Add a new feature to thr_kill, if thread ID argument is -1, send
signals to all threads except current sender.
-rw-r--r-- | sys/kern/kern_thr.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/sys/kern/kern_thr.c b/sys/kern/kern_thr.c index 6b67672..2a20bb1 100644 --- a/sys/kern/kern_thr.c +++ b/sys/kern/kern_thr.c @@ -310,19 +310,34 @@ thr_kill(struct thread *td, struct thr_kill_args *uap) p = td->td_proc; error = 0; PROC_LOCK(p); - ttd = thread_find(p, uap->id); - if (ttd == NULL) { - error = ESRCH; - goto out; - } - if (uap->sig == 0) - goto out; - if (!_SIG_VALID(uap->sig)) { - error = EINVAL; - goto out; + if (uap->id == -1) { + if (uap->sig != 0 && !_SIG_VALID(uap->sig)) { + error = EINVAL; + } else { + error = ESRCH; + FOREACH_THREAD_IN_PROC(p, ttd) { + if (ttd != td) { + error = 0; + if (uap->sig == 0) + break; + tdsignal(p, ttd, uap->sig, NULL); + } + } + } + } else { + if (uap->id != td->td_tid) + ttd = thread_find(p, uap->id); + else + ttd = td; + if (ttd == NULL) + error = ESRCH; + else if (uap->sig == 0) + ; + else if (!_SIG_VALID(uap->sig)) + error = EINVAL; + else + tdsignal(p, ttd, uap->sig, NULL); } - tdsignal(p, ttd, uap->sig, NULL); -out: PROC_UNLOCK(p); return (error); } |