]>
Commit | Line | Data |
---|---|---|
08c7dce5 AM |
1 | diff -up qt-everywhere-opensource-src-4.8.6/src/corelib/io/qprocess_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/corelib/io/qprocess_unix.cpp |
2 | --- qt-everywhere-opensource-src-4.8.6/src/corelib/io/qprocess_unix.cpp.poll 2014-03-30 15:36:48.000000000 -0500 | |
3 | +++ qt-everywhere-opensource-src-4.8.6/src/corelib/io/qprocess_unix.cpp 2014-03-31 18:04:05.958260978 -0500 | |
4 | @@ -158,13 +158,6 @@ static void qt_sa_sigchld_sigaction(int | |
5 | } | |
6 | } | |
7 | ||
8 | -static inline void add_fd(int &nfds, int fd, fd_set *fdset) | |
9 | -{ | |
10 | - FD_SET(fd, fdset); | |
11 | - if ((fd) > nfds) | |
12 | - nfds = fd; | |
13 | -} | |
14 | - | |
15 | struct QProcessInfo { | |
16 | QProcess *process; | |
17 | int deathPipe; | |
18 | @@ -256,9 +249,9 @@ QProcessManager::~QProcessManager() | |
19 | void QProcessManager::run() | |
20 | { | |
21 | forever { | |
22 | - fd_set readset; | |
23 | - FD_ZERO(&readset); | |
24 | - FD_SET(qt_qprocess_deadChild_pipe[0], &readset); | |
25 | + pollfd fd; | |
26 | + fd.fd = qt_qprocess_deadChild_pipe[0]; | |
27 | + fd.events = POLLIN; | |
28 | ||
29 | #if defined (QPROCESS_DEBUG) | |
30 | qDebug() << "QProcessManager::run() waiting for children to die"; | |
31 | @@ -267,8 +260,8 @@ void QProcessManager::run() | |
32 | // block forever, or until activity is detected on the dead child | |
33 | // pipe. the only other peers are the SIGCHLD signal handler, and the | |
34 | // QProcessManager destructor. | |
35 | - int nselect = select(qt_qprocess_deadChild_pipe[0] + 1, &readset, 0, 0, 0); | |
36 | - if (nselect < 0) { | |
37 | + int ret = qt_safe_poll(&fd, 1, -1, /* retry_eintr */ false); | |
38 | + if (ret < 0) { | |
39 | if (errno == EINTR) | |
40 | continue; | |
41 | break; | |
42 | @@ -1027,17 +1020,6 @@ void QProcessPrivate::killProcess() | |
43 | ::kill(pid_t(pid), SIGKILL); | |
44 | } | |
45 | ||
46 | -static int select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout) | |
47 | -{ | |
48 | - if (timeout < 0) | |
49 | - return qt_safe_select(nfds, fdread, fdwrite, 0, 0); | |
50 | - | |
51 | - struct timeval tv; | |
52 | - tv.tv_sec = timeout / 1000; | |
53 | - tv.tv_usec = (timeout % 1000) * 1000; | |
54 | - return qt_safe_select(nfds, fdread, fdwrite, 0, &tv); | |
55 | -} | |
56 | - | |
57 | /* | |
58 | Returns the difference between msecs and elapsed. If msecs is -1, | |
59 | however, -1 is returned. | |
60 | @@ -1060,10 +1042,10 @@ bool QProcessPrivate::waitForStarted(int | |
61 | childStartedPipe[0]); | |
62 | #endif | |
63 | ||
64 | - fd_set fds; | |
65 | - FD_ZERO(&fds); | |
66 | - FD_SET(childStartedPipe[0], &fds); | |
67 | - if (select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { | |
68 | + pollfd fd; | |
69 | + fd.fd = childStartedPipe[0]; | |
70 | + fd.events = POLLIN; | |
71 | + if (qt_safe_poll(&fd, 1, msecs) == 0) { | |
72 | processError = QProcess::Timedout; | |
73 | q->setErrorString(QProcess::tr("Process operation timed out")); | |
74 | #if defined (QPROCESS_DEBUG) | |
75 | @@ -1079,6 +1061,47 @@ bool QProcessPrivate::waitForStarted(int | |
76 | return startedEmitted; | |
77 | } | |
78 | ||
79 | +class QProcessFDSet { | |
80 | + pollfd fds[5]; | |
81 | + | |
82 | + static size_t size() | |
83 | + { | |
84 | + return sizeof(fds)/sizeof(fds[0]); | |
85 | + } | |
86 | + | |
87 | +public: | |
88 | + QProcessFDSet(QProcessPrivate &proc) | |
89 | + { | |
90 | + for (size_t i = 0; i < size(); ++i) { | |
91 | + fds[i].fd = -1; | |
92 | + fds[i].events = POLLIN; | |
93 | + } | |
94 | + death().fd = proc.deathPipe[0]; | |
95 | + | |
96 | + if (proc.processState == QProcess::Starting) | |
97 | + started().fd = proc.childStartedPipe[0]; | |
98 | + | |
99 | + stdout().fd = proc.stdoutChannel.pipe[0]; | |
100 | + stderr().fd = proc.stderrChannel.pipe[0]; | |
101 | + | |
102 | + if (!proc.writeBuffer.isEmpty()) { | |
103 | + stdin().fd = proc.stdinChannel.pipe[1]; | |
104 | + stdin().events = POLLOUT; | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + int poll(int timeout) | |
109 | + { | |
110 | + return qt_safe_poll(fds, size(), timeout); | |
111 | + } | |
112 | + | |
113 | + pollfd &death() { return fds[0]; } | |
114 | + pollfd &started() { return fds[1]; } | |
115 | + pollfd &stdout() { return fds[2]; } | |
116 | + pollfd &stderr() { return fds[3]; } | |
117 | + pollfd &stdin() { return fds[4]; } | |
118 | +}; | |
119 | + | |
120 | bool QProcessPrivate::waitForReadyRead(int msecs) | |
121 | { | |
122 | Q_Q(QProcess); | |
123 | @@ -1090,28 +1113,9 @@ bool QProcessPrivate::waitForReadyRead(i | |
124 | stopWatch.start(); | |
125 | ||
126 | forever { | |
127 | - fd_set fdread; | |
128 | - fd_set fdwrite; | |
129 | - | |
130 | - FD_ZERO(&fdread); | |
131 | - FD_ZERO(&fdwrite); | |
132 | - | |
133 | - int nfds = deathPipe[0]; | |
134 | - FD_SET(deathPipe[0], &fdread); | |
135 | - | |
136 | - if (processState == QProcess::Starting) | |
137 | - add_fd(nfds, childStartedPipe[0], &fdread); | |
138 | - | |
139 | - if (stdoutChannel.pipe[0] != -1) | |
140 | - add_fd(nfds, stdoutChannel.pipe[0], &fdread); | |
141 | - if (stderrChannel.pipe[0] != -1) | |
142 | - add_fd(nfds, stderrChannel.pipe[0], &fdread); | |
143 | - | |
144 | - if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) | |
145 | - add_fd(nfds, stdinChannel.pipe[1], &fdwrite); | |
146 | - | |
147 | + QProcessFDSet fdset(*this); | |
148 | int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); | |
149 | - int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); | |
150 | + int ret = fdset.poll(timeout); | |
151 | if (ret < 0) { | |
152 | break; | |
153 | } | |
154 | @@ -1121,18 +1125,18 @@ bool QProcessPrivate::waitForReadyRead(i | |
155 | return false; | |
156 | } | |
157 | ||
158 | - if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { | |
159 | + if (qt_readable(fdset.started())) { | |
160 | if (!_q_startupNotification()) | |
161 | return false; | |
162 | } | |
163 | ||
164 | bool readyReadEmitted = false; | |
165 | - if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) { | |
166 | + if (qt_readable(fdset.stdout())) { | |
167 | bool canRead = _q_canReadStandardOutput(); | |
168 | if (processChannel == QProcess::StandardOutput && canRead) | |
169 | readyReadEmitted = true; | |
170 | } | |
171 | - if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) { | |
172 | + if (qt_readable(fdset.stderr())) { | |
173 | bool canRead = _q_canReadStandardError(); | |
174 | if (processChannel == QProcess::StandardError && canRead) | |
175 | readyReadEmitted = true; | |
176 | @@ -1140,13 +1144,13 @@ bool QProcessPrivate::waitForReadyRead(i | |
177 | if (readyReadEmitted) | |
178 | return true; | |
179 | ||
180 | - if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) | |
181 | + if (qt_writable(fdset.stdin())) | |
182 | _q_canWrite(); | |
183 | ||
184 | - if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) { | |
185 | + if (qt_readable(fdset.death())) { | |
186 | if (_q_processDied()) | |
187 | return false; | |
188 | - } | |
189 | + } | |
190 | } | |
191 | return false; | |
192 | } | |
193 | @@ -1162,29 +1166,9 @@ bool QProcessPrivate::waitForBytesWritte | |
194 | stopWatch.start(); | |
195 | ||
196 | while (!writeBuffer.isEmpty()) { | |
197 | - fd_set fdread; | |
198 | - fd_set fdwrite; | |
199 | - | |
200 | - FD_ZERO(&fdread); | |
201 | - FD_ZERO(&fdwrite); | |
202 | - | |
203 | - int nfds = deathPipe[0]; | |
204 | - FD_SET(deathPipe[0], &fdread); | |
205 | - | |
206 | - if (processState == QProcess::Starting) | |
207 | - add_fd(nfds, childStartedPipe[0], &fdread); | |
208 | - | |
209 | - if (stdoutChannel.pipe[0] != -1) | |
210 | - add_fd(nfds, stdoutChannel.pipe[0], &fdread); | |
211 | - if (stderrChannel.pipe[0] != -1) | |
212 | - add_fd(nfds, stderrChannel.pipe[0], &fdread); | |
213 | - | |
214 | - | |
215 | - if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) | |
216 | - add_fd(nfds, stdinChannel.pipe[1], &fdwrite); | |
217 | - | |
218 | + QProcessFDSet fdset(*this); | |
219 | int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); | |
220 | - int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); | |
221 | + int ret = fdset.poll(timeout); | |
222 | if (ret < 0) { | |
223 | break; | |
224 | } | |
225 | @@ -1195,24 +1179,24 @@ bool QProcessPrivate::waitForBytesWritte | |
226 | return false; | |
227 | } | |
228 | ||
229 | - if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { | |
230 | + if (qt_readable(fdset.started())) { | |
231 | if (!_q_startupNotification()) | |
232 | return false; | |
233 | } | |
234 | ||
235 | - if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) | |
236 | + if (qt_writable(fdset.stdin())) | |
237 | return _q_canWrite(); | |
238 | ||
239 | - if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) | |
240 | + if (qt_readable(fdset.stdout())) | |
241 | _q_canReadStandardOutput(); | |
242 | ||
243 | - if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) | |
244 | + if (qt_readable(fdset.stderr())) | |
245 | _q_canReadStandardError(); | |
246 | ||
247 | - if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) { | |
248 | - if (_q_processDied()) | |
249 | - return false; | |
250 | - } | |
251 | + if (qt_readable(fdset.death())) { | |
252 | + if (_q_processDied()) | |
253 | + return false; | |
254 | + } | |
255 | } | |
256 | ||
257 | return false; | |
258 | @@ -1229,29 +1213,9 @@ bool QProcessPrivate::waitForFinished(in | |
259 | stopWatch.start(); | |
260 | ||
261 | forever { | |
262 | - fd_set fdread; | |
263 | - fd_set fdwrite; | |
264 | - int nfds = -1; | |
265 | - | |
266 | - FD_ZERO(&fdread); | |
267 | - FD_ZERO(&fdwrite); | |
268 | - | |
269 | - if (processState == QProcess::Starting) | |
270 | - add_fd(nfds, childStartedPipe[0], &fdread); | |
271 | - | |
272 | - if (stdoutChannel.pipe[0] != -1) | |
273 | - add_fd(nfds, stdoutChannel.pipe[0], &fdread); | |
274 | - if (stderrChannel.pipe[0] != -1) | |
275 | - add_fd(nfds, stderrChannel.pipe[0], &fdread); | |
276 | - | |
277 | - if (processState == QProcess::Running) | |
278 | - add_fd(nfds, deathPipe[0], &fdread); | |
279 | - | |
280 | - if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1) | |
281 | - add_fd(nfds, stdinChannel.pipe[1], &fdwrite); | |
282 | - | |
283 | + QProcessFDSet fdset(*this); | |
284 | int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); | |
285 | - int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); | |
286 | + int ret = fdset.poll(timeout); | |
287 | if (ret < 0) { | |
288 | break; | |
289 | } | |
290 | @@ -1261,20 +1225,20 @@ bool QProcessPrivate::waitForFinished(in | |
291 | return false; | |
292 | } | |
293 | ||
294 | - if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { | |
295 | + if (qt_readable(fdset.started())) { | |
296 | if (!_q_startupNotification()) | |
297 | return false; | |
298 | } | |
299 | - if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) | |
300 | + if (qt_writable(fdset.stdin())) | |
301 | _q_canWrite(); | |
302 | ||
303 | - if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) | |
304 | + if (qt_readable(fdset.stdout())) | |
305 | _q_canReadStandardOutput(); | |
306 | ||
307 | - if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) | |
308 | + if (qt_readable(fdset.stderr())) | |
309 | _q_canReadStandardError(); | |
310 | ||
311 | - if (deathPipe[0] == -1 || FD_ISSET(deathPipe[0], &fdread)) { | |
312 | + if (qt_readable(fdset.death())) { | |
313 | if (_q_processDied()) | |
314 | return true; | |
315 | } | |
316 | @@ -1284,10 +1248,10 @@ bool QProcessPrivate::waitForFinished(in | |
317 | ||
318 | bool QProcessPrivate::waitForWrite(int msecs) | |
319 | { | |
320 | - fd_set fdwrite; | |
321 | - FD_ZERO(&fdwrite); | |
322 | - FD_SET(stdinChannel.pipe[1], &fdwrite); | |
323 | - return select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; | |
324 | + pollfd fd; | |
325 | + fd.fd = stdinChannel.pipe[1]; | |
326 | + fd.events = POLLIN; | |
327 | + return qt_safe_poll(&fd, 1, msecs); | |
328 | } | |
329 | ||
330 | void QProcessPrivate::findExitCode() | |
331 | diff -up qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix.cpp | |
332 | --- qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix.cpp.poll 2014-03-30 15:36:48.000000000 -0500 | |
333 | +++ qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix.cpp 2014-03-31 18:01:59.369715403 -0500 | |
334 | @@ -99,4 +99,165 @@ int qt_safe_select(int nfds, fd_set *fdr | |
335 | } | |
336 | } | |
337 | ||
338 | +#ifndef Q_OS_VXWORKS | |
339 | + | |
340 | +int qt_safe_poll(struct pollfd *fds, int nfds, int timeout_ms, bool retry_eintr) | |
341 | +{ | |
342 | + if (nfds == 0) | |
343 | + return 0; | |
344 | + if (nfds < 0) { | |
345 | + errno = EINVAL; | |
346 | + return -1; | |
347 | + } | |
348 | + | |
349 | + // Retry on ret == 0 if the deadline has not yet passed because | |
350 | + // Linux can return early from the syscall, without setting EINTR. | |
351 | + if (timeout_ms < 0) { | |
352 | + forever { | |
353 | + int ret = ::poll(fds, nfds, -1); | |
354 | + if (ret > 0) | |
355 | + return ret; | |
356 | + if (retry_eintr) { | |
357 | + if (ret == 0 || ret == -1 && errno == EINTR) { | |
358 | + continue; | |
359 | + } else { | |
360 | + return -1; | |
361 | + } | |
362 | + } | |
363 | + if (ret == 0) { | |
364 | + errno = EINTR; | |
365 | + return -1; | |
366 | + } | |
367 | + return ret; | |
368 | + } | |
369 | + } | |
370 | + | |
371 | + timeval previous = qt_gettime(); | |
372 | + timeval deadline = previous; | |
373 | + deadline.tv_sec += timeout_ms / 1000; | |
374 | + deadline.tv_usec += (timeout_ms % 1000) * 1000; | |
375 | + if (deadline.tv_usec >= 1000000) { | |
376 | + ++deadline.tv_sec; | |
377 | + deadline.tv_usec -= 1000000; | |
378 | + } | |
379 | + int remaining = timeout_ms; | |
380 | + | |
381 | + forever { | |
382 | + int ret = ::poll(fds, nfds, remaining); | |
383 | + if (ret > 0) | |
384 | + return ret; | |
385 | + timeval now = qt_gettime(); | |
386 | + if ((now.tv_sec > deadline.tv_sec // past deadline | |
387 | + || (now.tv_sec == deadline.tv_sec | |
388 | + && now.tv_usec >= deadline.tv_usec)) | |
389 | + || (now.tv_sec < previous.tv_sec // time warp | |
390 | + || (now.tv_sec == previous.tv_sec | |
391 | + && now.tv_usec < previous.tv_usec)) | |
392 | + || (ret < 0 && (errno != EINTR || !retry_eintr))) // other error | |
393 | + return ret; | |
394 | + if (ret == 0 && !retry_eintr) { | |
395 | + errno = EINTR; | |
396 | + return -1; | |
397 | + } | |
398 | + remaining = (deadline.tv_sec - now.tv_sec) * 1000 | |
399 | + + (deadline.tv_usec - now.tv_usec) / 1000; | |
400 | + previous = now; | |
401 | + } | |
402 | +} | |
403 | + | |
404 | +#else | |
405 | + | |
406 | +// Poll emulation for VxWorks. | |
407 | + | |
408 | +static int mark_bad_descriptors(pollfd *fds, int nfds) | |
409 | +{ | |
410 | + fd_set r; | |
411 | + FD_ZERO(&r); | |
412 | + struct timeval tv; | |
413 | + tv.tv_sec = 0; | |
414 | + tv.tv_usec = 0; | |
415 | + int ret = 0; | |
416 | + | |
417 | + // Check each descriptor invidually for badness. | |
418 | + for (int i = 0; i < nfds; ++i) { | |
419 | + pollfd &fd(fds[i]); | |
420 | + if (fd.fd >= 0) { | |
421 | + FD_SET(fd.fd, &r); | |
422 | + int ret = qt_safe_select(fd.fd + 1, &r, NULL, NULL, &tv); | |
423 | + FD_CLR(fd.fd, &r); | |
424 | + if (ret < 0 && errno == EBADF) { | |
425 | + fd.revents = POLLNVAL; | |
426 | + ++ret; | |
427 | + } | |
428 | + } | |
429 | + } | |
430 | + Q_ASSERT(ret > 0); | |
431 | + return ret; | |
432 | +} | |
433 | + | |
434 | +int qt_safe_poll(pollfd *fds, int nfds, int timeout, bool retry_eintr) | |
435 | +{ | |
436 | + fd_set r, w; | |
437 | + FD_ZERO(&r); | |
438 | + FD_ZERO(&w); | |
439 | + int maxfd = -1; | |
440 | + | |
441 | + // Extract the watched descriptors. | |
442 | + for (int i = 0; i < nfds; ++i) { | |
443 | + pollfd &fd(fds[i]); | |
444 | + if (fd.fd >= 0 && fd.fd < FD_SETSIZE) { | |
445 | + if (fd.events & POLLIN) { | |
446 | + FD_SET(fd.fd, &r); | |
447 | + if (fd.fd > maxfd) | |
448 | + maxfd = fd.fd; | |
449 | + } | |
450 | + if (fd.events & POLLOUT) { | |
451 | + FD_SET(fd.fd, &w); | |
452 | + if (fd.fd > maxfd) | |
453 | + maxfd = fd.fd; | |
454 | + } | |
455 | + } | |
456 | + } | |
457 | + | |
458 | + // If timeout is negative, wait indefinitely for activity. | |
459 | + timeval tv; | |
460 | + timeval *ptv; | |
461 | + if (timeout >= 0) { | |
462 | + tv.tv_sec = timeout / 1000; | |
463 | + tv.tv_usec = (timeout % 1000) * 1000; | |
464 | + ptv = &tv; | |
465 | + } else | |
466 | + ptv = NULL; | |
467 | + | |
468 | + int ret; | |
469 | + if (retry_eintr) | |
470 | + ret = qt_safe_select(maxfd + 1, &r, &w, NULL, ptv); | |
471 | + else | |
472 | + ret = ::select(maxfd + 1, &r, &w, NULL, ptv); | |
473 | + if (ret < 0 && errno == EBADF) { | |
474 | + return mark_bad_descriptors(fds, nfds); | |
475 | + } | |
476 | + if (ret <= 0) | |
477 | + return ret; | |
478 | + | |
479 | + // Set the revents flags. | |
480 | + ret = 0; | |
481 | + for (int i = 0; i < nfds; ++i) { | |
482 | + pollfd &fd(fds[i]); | |
483 | + fd.revents = 0; | |
484 | + if (fd.fd >= 0 && fd.fd < FD_SETSIZE) { | |
485 | + if ((fd.events & POLLIN) && FD_ISSET(fd.fd, &r)) | |
486 | + fd.revents |= POLLIN; | |
487 | + if ((fd.events & POLLOUT) && FD_ISSET(fd.fd, &w)) | |
488 | + fd.revents |= POLLOUT; | |
489 | + if (fd.revents) | |
490 | + ++ret; | |
491 | + } | |
492 | + } | |
493 | + Q_ASSERT(ret > 0); | |
494 | + return ret; | |
495 | +} | |
496 | + | |
497 | +#endif | |
498 | + | |
499 | QT_END_NAMESPACE | |
500 | diff -up qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix_p.h.poll qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix_p.h | |
501 | --- qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix_p.h.poll 2014-03-30 15:36:48.000000000 -0500 | |
502 | +++ qt-everywhere-opensource-src-4.8.6/src/corelib/kernel/qcore_unix_p.h 2014-03-31 18:01:59.370715392 -0500 | |
503 | @@ -345,9 +345,42 @@ static inline pid_t qt_safe_waitpid(pid_ | |
504 | ||
505 | timeval qt_gettime(); // in qelapsedtimer_mac.cpp or qtimestamp_unix.cpp | |
506 | ||
507 | +// Deprecated due to FD_SETSIZE limitation, use qt_safe_poll instead. | |
508 | Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, | |
509 | const struct timeval *tv); | |
510 | ||
511 | +#ifndef Q_OS_VXWORKS | |
512 | +#include <poll.h> | |
513 | +#else | |
514 | + | |
515 | +// Poll emulation for VxWorks. | |
516 | + | |
517 | +struct pollfd { | |
518 | + int fd; | |
519 | + short events; | |
520 | + short revents; | |
521 | +}; | |
522 | + | |
523 | +#define POLLIN 1 | |
524 | +#define POLLOUT 2 | |
525 | +#define POLLERR 4 | |
526 | +#define POLLHUP 8 | |
527 | +#define POLLNVAL 16 | |
528 | +#endif | |
529 | + | |
530 | +inline bool qt_readable(const pollfd &fd) | |
531 | +{ | |
532 | + return fd.fd >= 0 && (fd.revents & (POLLIN | POLLHUP | POLLERR | POLLNVAL)) != 0; | |
533 | +} | |
534 | + | |
535 | +inline bool qt_writable(const pollfd &fd) | |
536 | +{ | |
537 | + return fd.fd >= 0 && (fd.revents & (POLLOUT | POLLHUP | POLLERR | POLLNVAL)) != 0; | |
538 | +} | |
539 | + | |
540 | +Q_CORE_EXPORT int qt_safe_poll(pollfd *fds, int nfds, int timeout, | |
541 | + bool retry_eintr = true); | |
542 | + | |
543 | // according to X/OPEN we have to define semun ourselves | |
544 | // we use prefix as on some systems sem.h will have it | |
545 | struct semid_ds; | |
546 | diff -up qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalserver_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalserver_unix.cpp | |
547 | --- qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalserver_unix.cpp.poll 2014-03-30 15:36:49.000000000 -0500 | |
548 | +++ qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalserver_unix.cpp 2014-03-31 18:01:59.370715392 -0500 | |
549 | @@ -208,16 +208,11 @@ void QLocalServerPrivate::_q_onNewConnec | |
550 | ||
551 | void QLocalServerPrivate::waitForNewConnection(int msec, bool *timedOut) | |
552 | { | |
553 | - fd_set readfds; | |
554 | - FD_ZERO(&readfds); | |
555 | - FD_SET(listenSocket, &readfds); | |
556 | + struct pollfd fd; | |
557 | + fd.fd = listenSocket; | |
558 | + fd.events = POLLIN; | |
559 | ||
560 | - timeval timeout; | |
561 | - timeout.tv_sec = msec / 1000; | |
562 | - timeout.tv_usec = (msec % 1000) * 1000; | |
563 | - | |
564 | - int result = -1; | |
565 | - result = qt_safe_select(listenSocket + 1, &readfds, 0, 0, (msec == -1) ? 0 : &timeout); | |
566 | + int result = qt_safe_poll(&fd, 1, msec); | |
567 | if (-1 == result) { | |
568 | setError(QLatin1String("QLocalServer::waitForNewConnection")); | |
569 | closeServer(); | |
570 | diff -up qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalsocket_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalsocket_unix.cpp | |
571 | --- qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalsocket_unix.cpp.poll 2014-03-30 15:36:49.000000000 -0500 | |
572 | +++ qt-everywhere-opensource-src-4.8.6/src/network/socket/qlocalsocket_unix.cpp 2014-03-31 18:01:59.370715392 -0500 | |
573 | @@ -56,10 +56,6 @@ | |
574 | #include <qdebug.h> | |
575 | #include <qelapsedtimer.h> | |
576 | ||
577 | -#ifdef Q_OS_VXWORKS | |
578 | -# include <selectLib.h> | |
579 | -#endif | |
580 | - | |
581 | #define QT_CONNECT_TIMEOUT 30000 | |
582 | ||
583 | QT_BEGIN_NAMESPACE | |
584 | @@ -520,32 +516,17 @@ bool QLocalSocket::waitForConnected(int | |
585 | if (state() != ConnectingState) | |
586 | return (state() == ConnectedState); | |
587 | ||
588 | - fd_set fds; | |
589 | - FD_ZERO(&fds); | |
590 | - FD_SET(d->connectingSocket, &fds); | |
591 | - | |
592 | - timeval timeout; | |
593 | - timeout.tv_sec = msec / 1000; | |
594 | - timeout.tv_usec = (msec % 1000) * 1000; | |
595 | - | |
596 | - // timeout can not be 0 or else select will return an error. | |
597 | - if (0 == msec) | |
598 | - timeout.tv_usec = 1000; | |
599 | + pollfd fd; | |
600 | + fd.fd = d->connectingSocket; | |
601 | + fd.events = POLLIN | POLLOUT; | |
602 | ||
603 | int result = -1; | |
604 | // on Linux timeout will be updated by select, but _not_ on other systems. | |
605 | QElapsedTimer timer; | |
606 | + int remaining = msec; | |
607 | timer.start(); | |
608 | - while (state() == ConnectingState | |
609 | - && (-1 == msec || timer.elapsed() < msec)) { | |
610 | -#ifdef Q_OS_SYMBIAN | |
611 | - // On Symbian, ready-to-write is signaled when non-blocking socket | |
612 | - // connect is finised. Is ready-to-read really used on other | |
613 | - // UNIX paltforms when using non-blocking AF_UNIX socket? | |
614 | - result = ::select(d->connectingSocket + 1, 0, &fds, 0, &timeout); | |
615 | -#else | |
616 | - result = ::select(d->connectingSocket + 1, &fds, 0, 0, &timeout); | |
617 | -#endif | |
618 | + while (state() == ConnectingState) { | |
619 | + result = qt_safe_poll(&fd, 1, remaining, /* retry_eintr */ false); | |
620 | if (-1 == result && errno != EINTR) { | |
621 | d->errorOccurred( QLocalSocket::UnknownSocketError, | |
622 | QLatin1String("QLocalSocket::waitForConnected")); | |
623 | @@ -553,6 +534,11 @@ bool QLocalSocket::waitForConnected(int | |
624 | } | |
625 | if (result > 0) | |
626 | d->_q_connectToSocket(); | |
627 | + if (msec >= 0) { | |
628 | + remaining = timer.elapsed() - msec; | |
629 | + if (remaining < 0) | |
630 | + break; | |
631 | + } | |
632 | } | |
633 | ||
634 | return (state() == ConnectedState); | |
635 | diff -up qt-everywhere-opensource-src-4.8.6/src/network/socket/qnativesocketengine_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/network/socket/qnativesocketengine_unix.cpp | |
636 | --- qt-everywhere-opensource-src-4.8.6/src/network/socket/qnativesocketengine_unix.cpp.poll 2014-03-30 15:36:49.000000000 -0500 | |
637 | +++ qt-everywhere-opensource-src-4.8.6/src/network/socket/qnativesocketengine_unix.cpp 2014-03-31 18:01:59.371715381 -0500 | |
638 | @@ -1068,48 +1068,40 @@ qint64 QNativeSocketEnginePrivate::nativ | |
639 | ||
640 | int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const | |
641 | { | |
642 | - fd_set fds; | |
643 | - FD_ZERO(&fds); | |
644 | - FD_SET(socketDescriptor, &fds); | |
645 | - | |
646 | - struct timeval tv; | |
647 | - tv.tv_sec = timeout / 1000; | |
648 | - tv.tv_usec = (timeout % 1000) * 1000; | |
649 | - | |
650 | - int retval; | |
651 | - if (selectForRead) | |
652 | - retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); | |
653 | - else | |
654 | - retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); | |
655 | - | |
656 | - return retval; | |
657 | + struct pollfd fd; | |
658 | + fd.fd = socketDescriptor; | |
659 | + if (selectForRead) { | |
660 | + fd.events = POLLIN; | |
661 | + } else { | |
662 | + fd.events = POLLOUT; | |
663 | + } | |
664 | + return qt_safe_poll(&fd, 1, timeout); | |
665 | } | |
666 | ||
667 | int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite, | |
668 | bool *selectForRead, bool *selectForWrite) const | |
669 | { | |
670 | - fd_set fdread; | |
671 | - FD_ZERO(&fdread); | |
672 | + struct pollfd fd; | |
673 | + fd.fd = socketDescriptor; | |
674 | if (checkRead) | |
675 | - FD_SET(socketDescriptor, &fdread); | |
676 | - | |
677 | - fd_set fdwrite; | |
678 | - FD_ZERO(&fdwrite); | |
679 | + fd.events = POLLIN; | |
680 | + else | |
681 | + fd.events = 0; | |
682 | if (checkWrite) | |
683 | - FD_SET(socketDescriptor, &fdwrite); | |
684 | - | |
685 | - struct timeval tv; | |
686 | - tv.tv_sec = timeout / 1000; | |
687 | - tv.tv_usec = (timeout % 1000) * 1000; | |
688 | - | |
689 | - int ret; | |
690 | - ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); | |
691 | - | |
692 | + fd.events |= POLLOUT; | |
693 | + int ret = qt_safe_poll(&fd, 1, timeout); | |
694 | if (ret <= 0) | |
695 | - return ret; | |
696 | - *selectForRead = FD_ISSET(socketDescriptor, &fdread); | |
697 | - *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite); | |
698 | - | |
699 | + return ret; | |
700 | + bool r = (fd.revents & (POLLIN | POLLHUP | POLLERR)) != 0; | |
701 | + bool w = (fd.revents & (POLLOUT | POLLHUP | POLLERR)) != 0; | |
702 | + // Emulate the return value from select(2). | |
703 | + ret = 0; | |
704 | + if (r) | |
705 | + ++ret; | |
706 | + if (w) | |
707 | + ++ret; | |
708 | + *selectForRead = r; | |
709 | + *selectForWrite = w; | |
710 | return ret; | |
711 | } | |
712 | ||
713 | diff -up qt-everywhere-opensource-src-4.8.6/src/qt3support/network/q3socketdevice_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/qt3support/network/q3socketdevice_unix.cpp | |
714 | --- qt-everywhere-opensource-src-4.8.6/src/qt3support/network/q3socketdevice_unix.cpp.poll 2014-03-30 15:36:49.000000000 -0500 | |
715 | +++ qt-everywhere-opensource-src-4.8.6/src/qt3support/network/q3socketdevice_unix.cpp 2014-03-31 18:01:59.371715381 -0500 | |
716 | @@ -68,6 +68,7 @@ static inline int qt_socket_socket(int d | |
717 | #endif | |
718 | ||
719 | #include "q3socketdevice.h" | |
720 | +#include "private/qcore_unix_p.h" | |
721 | ||
722 | #ifndef QT_NO_NETWORK | |
723 | ||
724 | @@ -588,19 +589,10 @@ Q_LONG Q3SocketDevice::waitForMore( int | |
725 | { | |
726 | if ( !isValid() ) | |
727 | return -1; | |
728 | - if ( fd >= FD_SETSIZE ) | |
729 | - return -1; | |
730 | - | |
731 | - fd_set fds; | |
732 | - struct timeval tv; | |
733 | - | |
734 | - FD_ZERO( &fds ); | |
735 | - FD_SET( fd, &fds ); | |
736 | - | |
737 | - tv.tv_sec = msecs / 1000; | |
738 | - tv.tv_usec = (msecs % 1000) * 1000; | |
739 | ||
740 | - int rv = select( fd+1, &fds, 0, 0, msecs < 0 ? 0 : &tv ); | |
741 | + pollfd pfd; | |
742 | + pfd.fd = fd; | |
743 | + int rv = qt_safe_poll(&pfd, 1, msecs, /* retry_eintr */ false); | |
744 | ||
745 | if ( rv < 0 ) | |
746 | return -1; | |
747 | diff -up qt-everywhere-opensource-src-4.8.6/src/qt3support/other/q3process_unix.cpp.poll qt-everywhere-opensource-src-4.8.6/src/qt3support/other/q3process_unix.cpp | |
748 | --- qt-everywhere-opensource-src-4.8.6/src/qt3support/other/q3process_unix.cpp.poll 2014-03-30 15:36:49.000000000 -0500 | |
749 | +++ qt-everywhere-opensource-src-4.8.6/src/qt3support/other/q3process_unix.cpp 2014-03-31 18:01:59.372715370 -0500 | |
750 | @@ -981,13 +981,10 @@ bool Q3Process::isRunning() const | |
751 | // On heavy processing, the socket notifier for the sigchild might not | |
752 | // have found time to fire yet. | |
753 | if ( d->procManager && d->procManager->sigchldFd[1] < FD_SETSIZE ) { | |
754 | - fd_set fds; | |
755 | - struct timeval tv; | |
756 | - FD_ZERO( &fds ); | |
757 | - FD_SET( d->procManager->sigchldFd[1], &fds ); | |
758 | - tv.tv_sec = 0; | |
759 | - tv.tv_usec = 0; | |
760 | - if ( ::select( d->procManager->sigchldFd[1]+1, &fds, 0, 0, &tv ) > 0 ) | |
761 | + pollfd fd; | |
762 | + fd.fd = d->procManager->sigchldFd[1]; | |
763 | + fd.events = POLLIN; | |
764 | + if ( qt_safe_poll(&fd, 1, 0, /* retry_eintr */ false) > 0 ) | |
765 | d->procManager->sigchldHnd( d->procManager->sigchldFd[1] ); | |
766 | } | |
767 | ||
768 | @@ -1124,29 +1121,21 @@ void Q3Process::socketRead( int fd ) | |
769 | } | |
770 | } | |
771 | ||
772 | - if ( fd < FD_SETSIZE ) { | |
773 | - fd_set fds; | |
774 | - struct timeval tv; | |
775 | - FD_ZERO( &fds ); | |
776 | - FD_SET( fd, &fds ); | |
777 | - tv.tv_sec = 0; | |
778 | - tv.tv_usec = 0; | |
779 | - while ( ::select( fd+1, &fds, 0, 0, &tv ) > 0 ) { | |
780 | - // prepare for the next round | |
781 | - FD_ZERO( &fds ); | |
782 | - FD_SET( fd, &fds ); | |
783 | - // read data | |
784 | - ba = new QByteArray( basize ); | |
785 | - n = ::read( fd, ba->data(), basize ); | |
786 | - if ( n > 0 ) { | |
787 | - ba->resize( n ); | |
788 | - buffer->append( ba ); | |
789 | - ba = 0; | |
790 | - } else { | |
791 | - delete ba; | |
792 | - ba = 0; | |
793 | - break; | |
794 | - } | |
795 | + pollfd pfd; | |
796 | + pfd.fd = fd; | |
797 | + pfd.events = POLLIN; | |
798 | + while (qt_safe_poll(&pfd, 1, 0)) { | |
799 | + // read data | |
800 | + ba = new QByteArray( basize ); | |
801 | + n = ::read( fd, ba->data(), basize ); | |
802 | + if ( n > 0 ) { | |
803 | + ba->resize( n ); | |
804 | + buffer->append( ba ); | |
805 | + ba = 0; | |
806 | + } else { | |
807 | + delete ba; | |
808 | + ba = 0; | |
809 | + break; | |
810 | } | |
811 | } | |
812 |