shithub: riscv

Download patch

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, &notefd) <= 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);