Blob


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