1 |
commit: b44bbe136afc2747df3f213467dd930c44454408 |
2 |
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Aug 27 19:48:25 2018 +0000 |
4 |
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org> |
5 |
CommitDate: Mon Aug 27 19:48:25 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=b44bbe13 |
7 |
|
8 |
sys-devel/make: Use a non-blocking read with pselect to avoid hangs |
9 |
|
10 |
Closes: https://bugs.gentoo.org/664632 |
11 |
Package-Manager: Portage-2.3.48, Repoman-2.3.10 |
12 |
|
13 |
.../files/make-4.2.1-pselect-non-blocking.patch | 172 +++++++++++++++++++++ |
14 |
sys-devel/make/make-4.2.1-r4.ebuild | 59 +++++++ |
15 |
2 files changed, 231 insertions(+) |
16 |
|
17 |
diff --git a/sys-devel/make/files/make-4.2.1-pselect-non-blocking.patch b/sys-devel/make/files/make-4.2.1-pselect-non-blocking.patch |
18 |
new file mode 100644 |
19 |
index 00000000000..61e19516f3c |
20 |
--- /dev/null |
21 |
+++ b/sys-devel/make/files/make-4.2.1-pselect-non-blocking.patch |
22 |
@@ -0,0 +1,172 @@ |
23 |
+https://bugs.gentoo.org/664632 |
24 |
+ |
25 |
+From b552b05251980f693c729e251f93f5225b400714 Mon Sep 17 00:00:00 2001 |
26 |
+From: Paul Smith <psmith@×××.org> |
27 |
+Date: Sat, 3 Jun 2017 16:20:51 -0400 |
28 |
+Subject: [SV 51159] Use a non-blocking read with pselect to avoid hangs. |
29 |
+ |
30 |
+* posixos.c (set_blocking): Set blocking on a file descriptor. |
31 |
+(jobserver_setup): Set non-blocking on the jobserver read side. |
32 |
+(jobserver_parse_auth): Ditto. |
33 |
+(jobserver_acquire_all): Set blocking to avoid a busy-wait loop. |
34 |
+(jobserver_acquire): If the non-blocking read() returns without |
35 |
+taking a token then try again. |
36 |
+--- |
37 |
+ posixos.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++----------------- |
38 |
+ 1 file changed, 71 insertions(+), 26 deletions(-) |
39 |
+ |
40 |
+diff --git a/posixos.c b/posixos.c |
41 |
+index e642d7f..dbafa51 100644 |
42 |
+--- a/posixos.c |
43 |
++++ b/posixos.c |
44 |
+@@ -62,6 +62,24 @@ make_job_rfd (void) |
45 |
+ #endif |
46 |
+ } |
47 |
+ |
48 |
++static void |
49 |
++set_blocking (int fd, int blocking) |
50 |
++{ |
51 |
++ // If we're not using pselect() don't change the blocking |
52 |
++#ifdef HAVE_PSELECT |
53 |
++ int flags; |
54 |
++ EINTRLOOP (flags, fcntl (fd, F_GETFL)); |
55 |
++ if (flags >= 0) |
56 |
++ { |
57 |
++ int r; |
58 |
++ flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK); |
59 |
++ EINTRLOOP (r, fcntl (fd, F_SETFL, flags)); |
60 |
++ if (r < 0) |
61 |
++ pfatal_with_name ("fcntl(O_NONBLOCK)"); |
62 |
++ } |
63 |
++#endif |
64 |
++} |
65 |
++ |
66 |
+ unsigned int |
67 |
+ jobserver_setup (int slots) |
68 |
+ { |
69 |
+@@ -86,6 +104,9 @@ jobserver_setup (int slots) |
70 |
+ pfatal_with_name (_("init jobserver pipe")); |
71 |
+ } |
72 |
+ |
73 |
++ /* When using pselect() we want the read to be non-blocking. */ |
74 |
++ set_blocking (job_fds[0], 0); |
75 |
++ |
76 |
+ return 1; |
77 |
+ } |
78 |
+ |
79 |
+@@ -121,6 +142,9 @@ jobserver_parse_auth (const char *auth) |
80 |
+ return 0; |
81 |
+ } |
82 |
+ |
83 |
++ /* When using pselect() we want the read to be non-blocking. */ |
84 |
++ set_blocking (job_fds[0], 0); |
85 |
++ |
86 |
+ return 1; |
87 |
+ } |
88 |
+ |
89 |
+@@ -169,7 +193,10 @@ jobserver_acquire_all (void) |
90 |
+ { |
91 |
+ unsigned int tokens = 0; |
92 |
+ |
93 |
+- /* Close the write side, so the read() won't hang. */ |
94 |
++ /* Use blocking reads to wait for all outstanding jobs. */ |
95 |
++ set_blocking (job_fds[0], 1); |
96 |
++ |
97 |
++ /* Close the write side, so the read() won't hang forever. */ |
98 |
+ close (job_fds[1]); |
99 |
+ job_fds[1] = -1; |
100 |
+ |
101 |
+@@ -236,18 +263,12 @@ jobserver_pre_acquire (void) |
102 |
+ unsigned int |
103 |
+ jobserver_acquire (int timeout) |
104 |
+ { |
105 |
+- sigset_t empty; |
106 |
+- fd_set readfds; |
107 |
+ struct timespec spec; |
108 |
+ struct timespec *specp = NULL; |
109 |
+- int r; |
110 |
+- char intake; |
111 |
++ sigset_t empty; |
112 |
+ |
113 |
+ sigemptyset (&empty); |
114 |
+ |
115 |
+- FD_ZERO (&readfds); |
116 |
+- FD_SET (job_fds[0], &readfds); |
117 |
+- |
118 |
+ if (timeout) |
119 |
+ { |
120 |
+ /* Alarm after one second (is this too granular?) */ |
121 |
+@@ -256,28 +277,52 @@ jobserver_acquire (int timeout) |
122 |
+ specp = &spec; |
123 |
+ } |
124 |
+ |
125 |
+- r = pselect (job_fds[0]+1, &readfds, NULL, NULL, specp, &empty); |
126 |
+- |
127 |
+- if (r == -1) |
128 |
++ while (1) |
129 |
+ { |
130 |
+- /* Better be SIGCHLD. */ |
131 |
+- if (errno != EINTR) |
132 |
+- pfatal_with_name (_("pselect jobs pipe")); |
133 |
+- return 0; |
134 |
+- } |
135 |
++ fd_set readfds; |
136 |
++ int r; |
137 |
++ char intake; |
138 |
+ |
139 |
+- if (r == 0) |
140 |
+- /* Timeout. */ |
141 |
+- return 0; |
142 |
++ FD_ZERO (&readfds); |
143 |
++ FD_SET (job_fds[0], &readfds); |
144 |
+ |
145 |
+- /* The read FD is ready: read it! */ |
146 |
+- EINTRLOOP (r, read (job_fds[0], &intake, 1)); |
147 |
+- if (r < 0) |
148 |
+- pfatal_with_name (_("read jobs pipe")); |
149 |
++ r = pselect (job_fds[0]+1, &readfds, NULL, NULL, specp, &empty); |
150 |
++ if (r < 0) |
151 |
++ switch (errno) |
152 |
++ { |
153 |
++ case EINTR: |
154 |
++ /* SIGCHLD will show up as an EINTR. */ |
155 |
++ return 0; |
156 |
++ |
157 |
++ case EBADF: |
158 |
++ /* Someone closed the jobs pipe. |
159 |
++ That shouldn't happen but if it does we're done. */ |
160 |
++ O (fatal, NILF, _("job server shut down")); |
161 |
+ |
162 |
+- /* What does it mean if read() returns 0? It shouldn't happen because only |
163 |
+- the master make can reap all the tokens and close the write side...?? */ |
164 |
+- return r > 0; |
165 |
++ default: |
166 |
++ pfatal_with_name (_("pselect jobs pipe")); |
167 |
++ } |
168 |
++ |
169 |
++ if (r == 0) |
170 |
++ /* Timeout. */ |
171 |
++ return 0; |
172 |
++ |
173 |
++ /* The read FD is ready: read it! This is non-blocking. */ |
174 |
++ EINTRLOOP (r, read (job_fds[0], &intake, 1)); |
175 |
++ |
176 |
++ if (r < 0) |
177 |
++ { |
178 |
++ /* Someone sniped our token! Try again. */ |
179 |
++ if (errno == EAGAIN) |
180 |
++ continue; |
181 |
++ |
182 |
++ pfatal_with_name (_("read jobs pipe")); |
183 |
++ } |
184 |
++ |
185 |
++ /* read() should never return 0: only the master make can reap all the |
186 |
++ tokens and close the write side...?? */ |
187 |
++ return r > 0; |
188 |
++ } |
189 |
+ } |
190 |
+ |
191 |
+ #else |
192 |
+-- |
193 |
+cgit v1.0-41-gc330 |
194 |
+ |
195 |
|
196 |
diff --git a/sys-devel/make/make-4.2.1-r4.ebuild b/sys-devel/make/make-4.2.1-r4.ebuild |
197 |
new file mode 100644 |
198 |
index 00000000000..fbc399d853b |
199 |
--- /dev/null |
200 |
+++ b/sys-devel/make/make-4.2.1-r4.ebuild |
201 |
@@ -0,0 +1,59 @@ |
202 |
+# Copyright 1999-2018 Gentoo Foundation |
203 |
+# Distributed under the terms of the GNU General Public License v2 |
204 |
+ |
205 |
+EAPI="6" |
206 |
+ |
207 |
+inherit flag-o-matic |
208 |
+ |
209 |
+DESCRIPTION="Standard tool to compile source trees" |
210 |
+HOMEPAGE="https://www.gnu.org/software/make/make.html" |
211 |
+SRC_URI="mirror://gnu//make/${P}.tar.bz2" |
212 |
+ |
213 |
+LICENSE="GPL-3+" |
214 |
+SLOT="0" |
215 |
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~ppc-aix ~x64-cygwin ~amd64-fbsd ~x86-fbsd ~amd64-linux ~arm-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~m68k-mint ~sparc-solaris ~sparc64-solaris ~x64-solaris ~x86-solaris" |
216 |
+IUSE="guile nls static" |
217 |
+ |
218 |
+CDEPEND="guile? ( >=dev-scheme/guile-1.8:= )" |
219 |
+DEPEND="${CDEPEND} |
220 |
+ nls? ( sys-devel/gettext )" |
221 |
+RDEPEND="${CDEPEND} |
222 |
+ nls? ( virtual/libintl )" |
223 |
+ |
224 |
+PATCHES=( |
225 |
+ "${FILESDIR}"/${PN}-3.82-darwin-library_search-dylib.patch |
226 |
+ "${FILESDIR}"/${PN}-4.2-default-cxx.patch |
227 |
+ "${FILESDIR}"/${PN}-4.2.1-perl526.patch |
228 |
+ "${FILESDIR}"/${PN}-4.2.1-glob-internals.patch |
229 |
+ "${FILESDIR}"/${PN}-4.2.1-pselect-non-blocking.patch |
230 |
+) |
231 |
+ |
232 |
+src_prepare() { |
233 |
+ default |
234 |
+ # These patches require special handling as they modify configure.ac |
235 |
+ # which in turn triggers maintainer-mode when being applied the |
236 |
+ # usual way. |
237 |
+ eapply -Z "${FILESDIR}"/${PN}-4.2.1-glob-v2.patch \ |
238 |
+ "${FILESDIR}"/${P}-guile-2.2.patch |
239 |
+} |
240 |
+ |
241 |
+src_configure() { |
242 |
+ use static && append-ldflags -static |
243 |
+ local myeconfargs=( |
244 |
+ --program-prefix=g |
245 |
+ $(use_with guile) |
246 |
+ $(use_enable nls) |
247 |
+ ) |
248 |
+ econf "${myeconfargs[@]}" |
249 |
+} |
250 |
+ |
251 |
+src_install() { |
252 |
+ emake DESTDIR="${D}" install |
253 |
+ dodoc AUTHORS NEWS README* |
254 |
+ if [[ ${USERLAND} == "GNU" ]] ; then |
255 |
+ # we install everywhere as 'gmake' but on GNU systems, |
256 |
+ # symlink 'make' to 'gmake' |
257 |
+ dosym gmake /usr/bin/make |
258 |
+ dosym gmake.1 /usr/share/man/man1/make.1 |
259 |
+ fi |
260 |
+} |