long
iocall(Ioproc *io, long (*op)(va_list*), ...)
{
- int ret, inted;
- Ioproc *msg;
+ Iocall r;
- if(send(io->c, &io) == -1){
+ r.op = op;
+ va_start(r.arg, op);
+ if(sendp(io->c, &r) < 0){
werrstr("interrupted");
return -1;
}
- assert(!io->inuse);
- io->inuse = 1;
- io->op = op;
- va_start(io->arg, op);
- msg = io;
- inted = 0;
- while(send(io->creply, &msg) == -1){
- msg = nil;
- inted = 1;
+ while(recv(io->creply, nil) < 0){
+ if(io->ctl < 0)
+ continue;
+ if(canqlock(io)){
+ if(++io->intr == 1)
+ write(io->ctl, "interrupt", 9);
+ qunlock(io);
+ }
}
- if(inted){
- werrstr("interrupted");
- return -1;
- }
-
- /*
- * If we get interrupted, we have to stick around so that
- * the IO proc has someone to talk to. Send it an interrupt
- * and try again.
- */
- inted = 0;
- while(recv(io->creply, nil) == -1){
- inted = 1;
- iointerrupt(io);
- }
- USED(inted);
- va_end(io->arg);
- ret = io->ret;
- if(ret < 0)
- errstr(io->err, sizeof io->err);
- io->inuse = 0;
-
- /* release resources */
- while(send(io->creply, &io) == -1)
- ;
- return ret;
+ va_end(r.arg);
+ if(r.ret < 0)
+ errstr(r.err, sizeof r.err);
+ return r.ret;
}