From 0df3f94ecdd32b5ee4ca3f8f8a73f4a7a455ddfb Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 9 Nov 2012 17:39:35 +0100 Subject: [PATCH] kbdfs: send interrupt note in separate proc to prevent potential deadlock --- sys/src/cmd/aux/kbdfs/kbdfs.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sys/src/cmd/aux/kbdfs/kbdfs.c b/sys/src/cmd/aux/kbdfs/kbdfs.c index 7373ef1b0..c33290b31 100644 --- a/sys/src/cmd/aux/kbdfs/kbdfs.c +++ b/sys/src/cmd/aux/kbdfs/kbdfs.c @@ -113,6 +113,7 @@ Channel *runechan; /* chan(Rune) */ Channel *conschan; /* chan(char*) */ Channel *kbdchan; /* chan(char*) */ +Channel *intchan; /* chan(int) */ /* * The codes at 0x79 and 0x7b are produced by the PFU Happy Hacking keyboard. @@ -543,6 +544,21 @@ Forward: } } +/* + * Need to do this in a separate proc because if process we're interrupting + * is dying and trying to print tombstone, kernel is blocked holding p->debug lock. + */ +void +intrproc(void *) +{ + threadsetname("intrproc"); + + for(;;){ + if(recv(intchan, nil) > 0) + write(notefd, "interrupt", 9); + } +} + /* * Cook lines for cons */ @@ -565,9 +581,8 @@ lineproc(void *aux) recv(cook, &r); switch(r){ case Kdel: - if(notefd < 0) + if(nbsend(intchan, ¬efd) <= 0) continue; - write(notefd, "interrupt", 9); /* no break */ case '\0': /* flush */ nr = 0; @@ -711,6 +726,8 @@ ctlproc(void *) proccreate(scanproc, nil, STACK); /* scanfd -> keychan */ if(consfd >= 0) proccreate(consproc, nil, STACK); /* consfd -> runechan */ + if(notefd >= 0) + proccreate(intrproc, nil, STACK); /* intchan -> notefd */ threadcreate(keyproc, nil, STACK); /* keychan -> rawchan, kbdchan */ threadcreate(runeproc, nil, STACK); /* rawchan -> runechan */ @@ -1382,6 +1399,7 @@ threadmain(int argc, char** argv) runechan = chancreate(sizeof(Rune), 32); conschan = chancreate(sizeof(char*), 16); kbdchan = chancreate(sizeof(char*), 16); + intchan = chancreate(sizeof(int), 0); elevate(); procrfork(ctlproc, nil, STACK, RFNAMEG|RFNOTEG);