Blob


1 #include <signal.h>
2 #include "threadimpl.h"
4 char *_threadexitsallstatus;
5 Channel *_threadwaitchan;
7 void
8 threadexits(char *exitstr)
9 {
10 Proc *p;
11 Thread *t;
13 p = _threadgetproc();
14 t = p->thread;
15 t->moribund = 1;
16 _threaddebug(DBGSCHED, "threadexits %s", exitstr);
17 if(exitstr==nil)
18 exitstr="";
19 utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr);
20 _sched();
21 }
23 void
24 threadexitsall(char *exitstr)
25 {
26 Proc *p;
27 int *pid;
28 int i, npid, mypid;
30 _threaddebug(DBGSCHED, "threadexitsall %s", exitstr);
31 if(exitstr == nil)
32 exitstr = "";
33 _threadexitsallstatus = exitstr;
34 _threaddebug(DBGSCHED, "_threadexitsallstatus set to %p", _threadexitsallstatus);
35 mypid = _threadgetpid();
37 /*
38 * signal others.
39 * copying all the pids first avoids other thread's
40 * teardown procedures getting in the way.
41 */
42 lock(&_threadpq.lock);
43 npid = 0;
44 for(p=_threadpq.head; p; p=p->next)
45 npid++;
46 pid = _threadmalloc(npid*sizeof(pid[0]), 0);
47 npid = 0;
48 for(p = _threadpq.head; p; p=p->next)
49 pid[npid++] = p->pid;
50 unlock(&_threadpq.lock);
51 for(i=0; i<npid; i++){
52 _threaddebug(DBGSCHED, "threadexitsall kill %d", pid[i]);
53 if(pid[i]==0 || pid[i]==-1)
54 fprint(2, "bad pid in threadexitsall: %d\n", pid[i]);
55 else if(pid[i] != mypid)
56 kill(pid[i], SIGTERM);
57 }
59 /* leave */
60 exit(0);
61 }
63 Channel*
64 threadwaitchan(void)
65 {
66 if(_threadwaitchan==nil)
67 _threadwaitchan = chancreate(sizeof(Waitmsg*), 16);
68 return _threadwaitchan;
69 }