ref: b092923c680af28f4841a123e55358f9a7d5e051
parent: 58d33065444feb44a518c48644f3bb2ba441c8fb
author: cinap_lenrek <cinap_lenrek@gmx.de>
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);
--
⑨