xref: /plan9/sys/src/libthread/ioproc.c (revision 6a9fc400c33447ef5e1cda7185cb4de2c8e8010e)
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include "threadimpl.h"
5 
6 enum
7 {
8 	STACK = 8192,
9 };
10 
11 static Ioproc *iofree;
12 
13 void
14 iointerrupt(Ioproc *io)
15 {
16 	if(!io->inuse)
17 		return;
18 	postnote(PNPROC, io->pid, "interrupt");
19 }
20 
21 static void
22 xioproc(void *a)
23 {
24 	Ioproc *io;
25 
26 	io = a;
27 	io->pid = getpid();
28 	sendp(io->c, nil);
29 	while(recvp(io->c) == io){
30 		io->ret = io->op(&io->arg);
31 		if(io->ret < 0)
32 			rerrstr(io->err, sizeof io->err);
33 		sendp(io->c, io);
34 	}
35 	chanfree(io->c);
36 	free(io);
37 }
38 
39 Ioproc*
40 ioproc(void)
41 {
42 	Ioproc *io;
43 
44 	if((io = iofree) != nil){
45 		iofree = io->next;
46 		return io;
47 	}
48 	io = mallocz(sizeof(*io), 1);
49 	if(io == nil)
50 		sysfatal("ioproc malloc: %r");
51 	io->c = chancreate(sizeof(void*), 0);
52 	if(proccreate(xioproc, io, STACK) < 0)
53 		sysfatal("ioproc proccreate: %r");
54 	recvp(io->c);
55 	return io;
56 }
57 
58 void
59 closeioproc(Ioproc *io)
60 {
61 	if(io == nil)
62 		return;
63 	iointerrupt(io);
64 	io->next = iofree;
65 	iofree = io;
66 }
67