xref: /plan9/sys/src/libthread/iocall.c (revision 5ab4dd4c205ee4af2f09166e9f81c4aec6598a6e)
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 long
iocall(Ioproc * io,long (* op)(va_list *),...)73ff48bf5SDavid du Colombier iocall(Ioproc *io, long (*op)(va_list*), ...)
83ff48bf5SDavid du Colombier {
97fd46167SDavid du Colombier 	int ret, inted;
107fd46167SDavid du Colombier 	Ioproc *msg;
113ff48bf5SDavid du Colombier 
127fd46167SDavid du Colombier 	if(send(io->c, &io) == -1){
137fd46167SDavid du Colombier 		werrstr("interrupted");
147fd46167SDavid du Colombier 		return -1;
157fd46167SDavid du Colombier 	}
163ff48bf5SDavid du Colombier 	assert(!io->inuse);
173ff48bf5SDavid du Colombier 	io->inuse = 1;
183ff48bf5SDavid du Colombier 	io->op = op;
193ff48bf5SDavid du Colombier 	va_start(io->arg, op);
207fd46167SDavid du Colombier 	msg = io;
217fd46167SDavid du Colombier 	inted = 0;
227fd46167SDavid du Colombier 	while(send(io->creply, &msg) == -1){
237fd46167SDavid du Colombier 		msg = nil;
247fd46167SDavid du Colombier 		inted = 1;
257fd46167SDavid du Colombier 	}
267fd46167SDavid du Colombier 	if(inted){
277fd46167SDavid du Colombier 		werrstr("interrupted");
287fd46167SDavid du Colombier 		return -1;
297fd46167SDavid du Colombier 	}
307fd46167SDavid du Colombier 
317fd46167SDavid du Colombier 	/*
32*5ab4dd4cSDavid du Colombier 	 * If we get interrupted, we have to stick around so that
337fd46167SDavid du Colombier 	 * the IO proc has someone to talk to.  Send it an interrupt
347fd46167SDavid du Colombier 	 * and try again.
357fd46167SDavid du Colombier 	 */
367fd46167SDavid du Colombier 	inted = 0;
377fd46167SDavid du Colombier 	while(recv(io->creply, nil) == -1){
387fd46167SDavid du Colombier 		inted = 1;
397fd46167SDavid du Colombier 		iointerrupt(io);
407fd46167SDavid du Colombier 	}
417fd46167SDavid du Colombier 	USED(inted);
423ff48bf5SDavid du Colombier 	va_end(io->arg);
433ff48bf5SDavid du Colombier 	ret = io->ret;
443ff48bf5SDavid du Colombier 	if(ret < 0)
453ff48bf5SDavid du Colombier 		errstr(io->err, sizeof io->err);
463ff48bf5SDavid du Colombier 	io->inuse = 0;
477fd46167SDavid du Colombier 
487fd46167SDavid du Colombier 	/* release resources */
497fd46167SDavid du Colombier 	while(send(io->creply, &io) == -1)
507fd46167SDavid du Colombier 		;
513ff48bf5SDavid du Colombier 	return ret;
523ff48bf5SDavid du Colombier }
53