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