13ff48bf5SDavid du Colombier #include <u.h>
23ff48bf5SDavid du Colombier #include <libc.h>
33ff48bf5SDavid du Colombier #include <thread.h>
43ff48bf5SDavid du Colombier #include "threadimpl.h"
53ff48bf5SDavid du Colombier
63ff48bf5SDavid du Colombier enum
73ff48bf5SDavid du Colombier {
83ff48bf5SDavid du Colombier STACK = 8192,
93ff48bf5SDavid du Colombier };
103ff48bf5SDavid du Colombier
113ff48bf5SDavid du Colombier void
iointerrupt(Ioproc * io)123ff48bf5SDavid du Colombier iointerrupt(Ioproc *io)
133ff48bf5SDavid du Colombier {
143ff48bf5SDavid du Colombier if(!io->inuse)
153ff48bf5SDavid du Colombier return;
16*7fd46167SDavid du Colombier threadint(io->tid);
173ff48bf5SDavid du Colombier }
183ff48bf5SDavid du Colombier
193ff48bf5SDavid du Colombier static void
xioproc(void * a)203ff48bf5SDavid du Colombier xioproc(void *a)
213ff48bf5SDavid du Colombier {
22*7fd46167SDavid du Colombier Ioproc *io, *x;
233ff48bf5SDavid du Colombier io = a;
24*7fd46167SDavid du Colombier /*
25*7fd46167SDavid du Colombier * first recvp acquires the ioproc.
26*7fd46167SDavid du Colombier * second tells us that the data is ready.
27*7fd46167SDavid du Colombier */
28*7fd46167SDavid du Colombier for(;;){
29*7fd46167SDavid du Colombier while(recv(io->c, &x) == -1)
30*7fd46167SDavid du Colombier ;
31*7fd46167SDavid du Colombier if(x == 0) /* our cue to leave */
32*7fd46167SDavid du Colombier break;
33*7fd46167SDavid du Colombier assert(x == io);
34*7fd46167SDavid du Colombier
35*7fd46167SDavid du Colombier /* caller is now committed -- even if interrupted he'll return */
36*7fd46167SDavid du Colombier while(recv(io->creply, &x) == -1)
37*7fd46167SDavid du Colombier ;
38*7fd46167SDavid du Colombier if(x == 0) /* caller backed out */
39*7fd46167SDavid du Colombier continue;
40*7fd46167SDavid du Colombier assert(x == io);
41*7fd46167SDavid du Colombier
423ff48bf5SDavid du Colombier io->ret = io->op(&io->arg);
433ff48bf5SDavid du Colombier if(io->ret < 0)
443ff48bf5SDavid du Colombier rerrstr(io->err, sizeof io->err);
45*7fd46167SDavid du Colombier while(send(io->creply, &io) == -1)
46*7fd46167SDavid du Colombier ;
47*7fd46167SDavid du Colombier while(recv(io->creply, &x) == -1)
48*7fd46167SDavid du Colombier ;
493ff48bf5SDavid du Colombier }
503ff48bf5SDavid du Colombier }
513ff48bf5SDavid du Colombier
523ff48bf5SDavid du Colombier Ioproc*
ioproc(void)533ff48bf5SDavid du Colombier ioproc(void)
543ff48bf5SDavid du Colombier {
553ff48bf5SDavid du Colombier Ioproc *io;
563ff48bf5SDavid du Colombier
573ff48bf5SDavid du Colombier io = mallocz(sizeof(*io), 1);
583ff48bf5SDavid du Colombier if(io == nil)
593ff48bf5SDavid du Colombier sysfatal("ioproc malloc: %r");
603ff48bf5SDavid du Colombier io->c = chancreate(sizeof(void*), 0);
61*7fd46167SDavid du Colombier io->creply = chancreate(sizeof(void*), 0);
62*7fd46167SDavid du Colombier io->tid = proccreate(xioproc, io, STACK);
633ff48bf5SDavid du Colombier return io;
643ff48bf5SDavid du Colombier }
653ff48bf5SDavid du Colombier
663ff48bf5SDavid du Colombier void
closeioproc(Ioproc * io)673ff48bf5SDavid du Colombier closeioproc(Ioproc *io)
683ff48bf5SDavid du Colombier {
693ff48bf5SDavid du Colombier if(io == nil)
703ff48bf5SDavid du Colombier return;
713ff48bf5SDavid du Colombier iointerrupt(io);
72*7fd46167SDavid du Colombier while(send(io->c, 0) == -1)
73*7fd46167SDavid du Colombier ;
74*7fd46167SDavid du Colombier chanfree(io->c);
75*7fd46167SDavid du Colombier chanfree(io->creply);
76*7fd46167SDavid du Colombier free(io);
773ff48bf5SDavid du Colombier }
78