ref: 0df3f94ecdd32b5ee4ca3f8f8a73f4a7a455ddfb
parent: 663aff7fb2394784e4d5565f57f84a43d69115b9
author: cinap_lenrek <[email protected]>
date: Fri Nov 9 12:39:35 EST 2012
kbdfs: send interrupt note in separate proc to prevent potential deadlock
--- a/sys/src/cmd/aux/kbdfs/kbdfs.c
+++ b/sys/src/cmd/aux/kbdfs/kbdfs.c
@@ -113,6 +113,7 @@
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.
@@ -544,6 +545,21 @@
}
/*
+ * 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
*/
void
@@ -565,9 +581,8 @@
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 @@
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 @@
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);