aboutsummaryrefslogtreecommitdiff
path: root/src/libthread/exit.c
blob: ddf700143ac55e0cc7c538621ce673c186cafdb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include "threadimpl.h"
#include <signal.h>

char *_threadexitsallstatus;
Channel *_threadwaitchan;

void
threadexits(char *exitstr)
{
	Proc *p;
	Thread *t;

	p = _threadgetproc();
	t = p->thread;
	t->moribund = 1;
	if(exitstr==nil)
		exitstr="";
	utfecpy(p->exitstr, p->exitstr+ERRMAX, exitstr);
	_sched();
}

void
threadexitsall(char *exitstr)
{
	Proc *p;
	int *pid;
	int i, npid, mypid;

	if(exitstr == nil)
		exitstr = "";
	_threadexitsallstatus = exitstr;
	_threaddebug(DBGSCHED, "_threadexitsallstatus set to %p", _threadexitsallstatus);
	mypid = _threadgetpid();

	/*
	 * signal others.
	 * copying all the pids first avoids other threads
	 * teardown procedures getting in the way.
	 */
	lock(&_threadpq.lock);
	npid = 0;
	for(p=_threadpq.head; p; p=p->next)
		npid++;
	pid = _threadmalloc(npid*sizeof(pid[0]), 0);
	npid = 0;
	for(p = _threadpq.head; p; p=p->next)
		pid[npid++] = p->pid;
	unlock(&_threadpq.lock);
	for(i=0; i<npid; i++)
		if(pid[i] != mypid)
			kill(pid[i], SIGTERM);

	/* leave */
	exit(0);
}

Channel*
threadwaitchan(void)
{
	if(_threadwaitchan==nil)
		_threadwaitchan = chancreate(sizeof(Waitmsg*), 16);
	return _threadwaitchan;
}