| 1 |
Title : x11-base/xorg-server-1.3 and 1.4 consumes 100% CPU, locking the ke
|
| 2 |
yboard, apparently triggered by opening an OpenOffice pulldown menu
|
| 3 |
Assignee : x11@gentoo.org
|
| 4 |
Reported : 2007-10-26 03:51 0000
|
| 5 |
Updated : 2007-11-07 07:21:56 0000
|
| 6 |
Status : NEW
|
| 7 |
URL : https://bugs.freedesktop.org/show_bug.cgi?id=10525
|
| 8 |
Severity : critical
|
| 9 |
Priority : P2
|
| 10 |
Reporter : smw@alcor.concordia.ca
|
| 11 |
Product : Gentoo Linux
|
| 12 |
Component : Server
|
| 13 |
Keywords : Inclusion
|
| 14 |
CC : tetromino@gmail.com
|
| 15 |
Comments : 3
|
| 16 |
Attachments : 0
|
| 17 |
URL : http://bugs.gentoo.org/show_bug.cgi?id=197104
|
| 18 |
|
| 19 |
commit a5b8053606d6e786cdcf6734f271acc05f9cc588
|
| 20 |
Author: Adam Jackson <ajax@benzedrine.nwnk.net>
|
| 21 |
Date: Tue Sep 11 11:37:06 2007 -0400
|
| 22 |
|
| 23 |
Ignore - not just block - SIGALRM around Popen()/Pclose().
|
| 24 |
|
| 25 |
Because our "popen" implementation uses stdio, and because nobody's stdio
|
| 26 |
library is capable of surviving signals, we need to make absolutely sure
|
| 27 |
that we hide the SIGALRM from the smart scheduler. Otherwise, when you
|
| 28 |
open a menu in openoffice, and it recompiles XKB to deal with the
|
| 29 |
accelerators, and you popen xkbcomp because we suck, then the scheduler
|
| 30 |
will tell you you're taking forever doing something stupid, and the
|
| 31 |
wait() code will get confused, and input will hang and your CPU usage
|
| 32 |
slams to 100%. Down, not across.
|
| 33 |
|
| 34 |
diff --git a/os/utils.c b/os/utils.c
|
| 35 |
index 3bb7dbe..afcaae4 100644
|
| 36 |
--- a/os/utils.c
|
| 37 |
+++ b/os/utils.c
|
| 38 |
@@ -1720,6 +1720,8 @@ static struct pid {
|
| 39 |
int pid;
|
| 40 |
} *pidlist;
|
| 41 |
|
| 42 |
+static sighandler_t old_alarm = NULL; /* XXX horrible awful hack */
|
| 43 |
+
|
| 44 |
pointer
|
| 45 |
Popen(char *command, char *type)
|
| 46 |
{
|
| 47 |
@@ -1741,11 +1743,15 @@ Popen(char *command, char *type)
|
| 48 |
return NULL;
|
| 49 |
}
|
| 50 |
|
| 51 |
+ /* Ignore the smart scheduler while this is going on */
|
| 52 |
+ old_alarm = signal(SIGALRM, SIG_IGN);
|
| 53 |
+
|
| 54 |
switch (pid = fork()) {
|
| 55 |
case -1: /* error */
|
| 56 |
close(pdes[0]);
|
| 57 |
close(pdes[1]);
|
| 58 |
xfree(cur);
|
| 59 |
+ signal(SIGALRM, old_alarm);
|
| 60 |
return NULL;
|
| 61 |
case 0: /* child */
|
| 62 |
if (setgid(getgid()) == -1)
|
| 63 |
@@ -1921,6 +1927,8 @@ Pclose(pointer iop)
|
| 64 |
/* allow EINTR again */
|
| 65 |
OsReleaseSignals ();
|
| 66 |
|
| 67 |
+ signal(SIGALRM, old_alarm);
|
| 68 |
+
|
| 69 |
return pid == -1 ? -1 : pstat;
|
| 70 |
}
|
| 71 |
|