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