diff options
author | cinap_lenrek <cinap_lenrek@localhost> | 2011-08-22 03:03:27 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-08-22 03:03:27 +0200 |
commit | 08c39320a46ad94fba9ba3310444f136dd9258f5 (patch) | |
tree | 4b98ada862770a8734f0c72240f7bab4a28c8d31 /sys/src/libthread/ioproc.c | |
parent | 9a90e50142c792fdc06dc4faa8a582f441124aad (diff) |
libthread: reimplemented i/o procs using new interrupt ctl message
Diffstat (limited to 'sys/src/libthread/ioproc.c')
-rw-r--r-- | sys/src/libthread/ioproc.c | 92 |
1 files changed, 57 insertions, 35 deletions
diff --git a/sys/src/libthread/ioproc.c b/sys/src/libthread/ioproc.c index e5452ad35..8a02e23e0 100644 --- a/sys/src/libthread/ioproc.c +++ b/sys/src/libthread/ioproc.c @@ -11,55 +11,80 @@ enum void iointerrupt(Ioproc *io) { - if(!io->inuse) - return; - threadint(io->tid); + qlock(io); + if(++io->intr == 1) + write(io->ctl, "interrupt", 9); + qunlock(io); } static void xioproc(void *a) { - Ioproc *io, *x; - io = a; - /* - * first recvp acquires the ioproc. - * second tells us that the data is ready. - */ - for(;;){ - while(recv(io->c, &x) == -1) - ; - if(x == 0) /* our cue to leave */ - break; - assert(x == io); + Channel *c; + Ioproc *io; + Iocall *r; - /* caller is now committed -- even if interrupted he'll return */ - while(recv(io->creply, &x) == -1) - ; - if(x == 0) /* caller backed out */ - continue; - assert(x == io); + c = a; + if(io = mallocz(sizeof(*io), 1)){ + char buf[128]; + + snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid()); + if((io->ctl = open(buf, OWRITE)) < 0){ + free(io); + io = nil; + } else { + if((io->creply = chancreate(sizeof(void*), 0)) == nil){ + close(io->ctl); + free(io); + io = nil; + } else + io->c = c; + } + } + while(send(c, &io) < 0) + ; + if(io == nil) + return; - io->ret = io->op(&io->arg); - if(io->ret < 0) - rerrstr(io->err, sizeof io->err); - while(send(io->creply, &io) == -1) + for(;;){ + while(recv(io->c, &r) < 0) ; - while(recv(io->creply, &x) == -1) + if(r == 0) + break; + if(io->intr){ + r->ret = -1; + strcpy(r->err, "interrupted"); + } else if((r->ret = r->op(&r->arg)) < 0) + rerrstr(r->err, sizeof r->err); + qlock(io); + if(io->intr){ + io->intr = 0; + write(io->ctl, "nointerrupt", 11); + } + while(send(io->creply, &r) < 0) ; + qunlock(io); } + + close(io->ctl); + chanfree(io->c); + chanfree(io->creply); + free(io); } Ioproc* ioproc(void) { + Channel *c; Ioproc *io; - io = mallocz(sizeof(*io), 1); + if((c = chancreate(sizeof(void*), 0)) == nil) + sysfatal("ioproc chancreate"); + proccreate(xioproc, c, STACK); + while(recv(c, &io) < 0) + ; if(io == nil) - sysfatal("ioproc malloc: %r"); - io->c = chancreate(sizeof(void*), 0); - io->creply = chancreate(sizeof(void*), 0); - io->tid = proccreate(xioproc, io, STACK); + sysfatal("ioproc alloc"); return io; } @@ -69,9 +94,6 @@ closeioproc(Ioproc *io) if(io == nil) return; iointerrupt(io); - while(send(io->c, 0) == -1) + while(sendp(io->c, nil) < 0) ; - chanfree(io->c); - chanfree(io->creply); - free(io); } |