From 2e49b7a3b99a0f02c2521656fa2f573c2ea40150 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 19 Feb 2014 11:01:00 +0100 Subject: [PATCH] BB select(): move special select method to qcore_unix_p.h ... and make it independent of QProcess, because we want to use it from QtNetwork as well. In addition, move select_msecs() to qcore_unix_p.h as well and rename it to qt_select_msecs(). Task-number: QTBUG-36144 Change-Id: Ief681b6f6c80e85aa5091a5a04bcedb60f353217 Reviewed-by: Oswald Buddenhagen Reviewed-by: Rafael Roquetto Reviewed-by: Thiago Macieira --- src/corelib/io/qprocess_p.h | 5 ++ src/corelib/io/qprocess_unix.cpp | 85 +++++++++++-------------------- src/corelib/kernel/qcore_unix.cpp | 43 ++++++++++++++++ src/corelib/kernel/qcore_unix_p.h | 8 +++ 4 files changed, 87 insertions(+), 54 deletions(-) diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 219bdf8200..5d65b2a068 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -390,6 +390,11 @@ public: qint64 writeToStdin(const char *data, qint64 maxlen); void cleanup(); + +#ifdef Q_OS_BLACKBERRY + QList defaultNotifiers() const; +#endif // Q_OS_BLACKBERRY + #ifdef Q_OS_UNIX static void initializeProcessManager(); #endif diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 0e917ef438..8674371baa 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -1042,17 +1042,6 @@ void QProcessPrivate::killProcess() ::kill(pid_t(pid), SIGKILL); } -static int select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout) -{ - if (timeout < 0) - return qt_safe_select(nfds, fdread, fdwrite, 0, 0); - - struct timespec tv; - tv.tv_sec = timeout / 1000; - tv.tv_nsec = (timeout % 1000) * 1000 * 1000; - return qt_safe_select(nfds, fdread, fdwrite, 0, &tv); -} - /* Returns the difference between msecs and elapsed. If msecs is -1, however, -1 is returned. @@ -1066,41 +1055,6 @@ static int qt_timeout_value(int msecs, int elapsed) return timeout < 0 ? 0 : timeout; } -#ifdef Q_OS_BLACKBERRY -// The BlackBerry event dispatcher uses bps_get_event. Unfortunately, already registered -// socket notifiers are disabled by a call to select. This is to rearm the standard streams. -static int bb_select(QProcessPrivate *process, int nfds, fd_set *fdread, fd_set *fdwrite, int timeout) -{ - bool stdoutEnabled = false; - bool stderrEnabled = false; - bool stdinEnabled = false; - - if (process->stdoutChannel.notifier && process->stdoutChannel.notifier->isEnabled()) { - stdoutEnabled = true; - process->stdoutChannel.notifier->setEnabled(false); - } - if (process->stderrChannel.notifier && process->stderrChannel.notifier->isEnabled()) { - stderrEnabled = true; - process->stderrChannel.notifier->setEnabled(false); - } - if (process->stdinChannel.notifier && process->stdinChannel.notifier->isEnabled()) { - stdinEnabled = true; - process->stdinChannel.notifier->setEnabled(false); - } - - const int ret = select_msecs(nfds, fdread, fdwrite, timeout); - - if (stdoutEnabled) - process->stdoutChannel.notifier->setEnabled(true); - if (stderrEnabled) - process->stderrChannel.notifier->setEnabled(true); - if (stdinEnabled) - process->stdinChannel.notifier->setEnabled(true); - - return ret; -} -#endif // Q_OS_BLACKBERRY - bool QProcessPrivate::waitForStarted(int msecs) { Q_Q(QProcess); @@ -1113,7 +1067,7 @@ bool QProcessPrivate::waitForStarted(int msecs) fd_set fds; FD_ZERO(&fds); FD_SET(childStartedPipe[0], &fds); - if (select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { + if (qt_select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { processError = QProcess::Timedout; q->setErrorString(QProcess::tr("Process operation timed out")); #if defined (QPROCESS_DEBUG) @@ -1129,6 +1083,17 @@ bool QProcessPrivate::waitForStarted(int msecs) return startedEmitted; } +#ifdef Q_OS_BLACKBERRY +QList QProcessPrivate::defaultNotifiers() const +{ + QList notifiers; + notifiers << stdoutChannel.notifier + << stderrChannel.notifier + << stdinChannel.notifier; + return notifiers; +} +#endif // Q_OS_BLACKBERRY + bool QProcessPrivate::waitForReadyRead(int msecs) { Q_Q(QProcess); @@ -1139,6 +1104,10 @@ bool QProcessPrivate::waitForReadyRead(int msecs) QElapsedTimer stopWatch; stopWatch.start(); +#ifdef Q_OS_BLACKBERRY + QList notifiers = defaultNotifiers(); +#endif + forever { fd_set fdread; fd_set fdwrite; @@ -1162,9 +1131,9 @@ bool QProcessPrivate::waitForReadyRead(int msecs) int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); #ifdef Q_OS_BLACKBERRY - int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout); + int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout); #else - int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); + int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout); #endif if (ret < 0) { break; @@ -1215,6 +1184,10 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) QElapsedTimer stopWatch; stopWatch.start(); +#ifdef Q_OS_BLACKBERRY + QList notifiers = defaultNotifiers(); +#endif + while (!writeBuffer.isEmpty()) { fd_set fdread; fd_set fdwrite; @@ -1239,9 +1212,9 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); #ifdef Q_OS_BLACKBERRY - int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout); + int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout); #else - int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); + int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout); #endif if (ret < 0) { break; @@ -1286,6 +1259,10 @@ bool QProcessPrivate::waitForFinished(int msecs) QElapsedTimer stopWatch; stopWatch.start(); +#ifdef Q_OS_BLACKBERRY + QList notifiers = defaultNotifiers(); +#endif + forever { fd_set fdread; fd_set fdwrite; @@ -1310,9 +1287,9 @@ bool QProcessPrivate::waitForFinished(int msecs) int timeout = qt_timeout_value(msecs, stopWatch.elapsed()); #ifdef Q_OS_BLACKBERRY - int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout); + int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout); #else - int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout); + int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout); #endif if (ret < 0) { break; @@ -1349,7 +1326,7 @@ bool QProcessPrivate::waitForWrite(int msecs) fd_set fdwrite; FD_ZERO(&fdwrite); FD_SET(stdinChannel.pipe[1], &fdwrite); - return select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; + return qt_select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; } void QProcessPrivate::findExitCode() diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index e4181b5c86..8d788419fb 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -58,6 +58,10 @@ #include #endif +#ifdef Q_OS_BLACKBERRY +#include +#endif // Q_OS_BLACKBERRY + QT_BEGIN_NAMESPACE static inline bool time_update(struct timespec *tv, const struct timespec &start, @@ -106,4 +110,43 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, } } +int qt_select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout) +{ + if (timeout < 0) + return qt_safe_select(nfds, fdread, fdwrite, 0, 0); + + struct timespec tv; + tv.tv_sec = timeout / 1000; + tv.tv_nsec = (timeout % 1000) * 1000 * 1000; + return qt_safe_select(nfds, fdread, fdwrite, 0, &tv); +} + +#ifdef Q_OS_BLACKBERRY +// The BlackBerry event dispatcher uses bps_get_event. Unfortunately, already registered +// socket notifiers are disabled by a call to select. This is to rearm the standard streams. +int bb_select(QList socketNotifiers, int nfds, fd_set *fdread, fd_set *fdwrite, + int timeout) +{ + QList socketNotifiersEnabled; + socketNotifiersEnabled.reserve(socketNotifiers.count()); + for (int a = 0; a < socketNotifiers.count(); ++a) { + if (socketNotifiers.at(a) && socketNotifiers.at(a)->isEnabled()) { + socketNotifiersEnabled[a] = true; + socketNotifiers.at(a)->setEnabled(false); + } else { + socketNotifiersEnabled[a] = false; + } + } + + const int ret = qt_select_msecs(nfds, fdread, fdwrite, timeout); + + for (int a = 0; a < socketNotifiers.count(); ++a) { + if (socketNotifiersEnabled.at(a) == true) + socketNotifiers.at(a)->setEnabled(true); + } + + return ret; +} +#endif // Q_OS_BLACKBERRY + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 7ab632d7a0..df78ef6692 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -343,6 +343,14 @@ void qt_nanosleep(timespec amount); Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, const struct timespec *tv); +int qt_select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout); + +#ifdef Q_OS_BLACKBERRY +class QSocketNotifier; +Q_CORE_EXPORT int bb_select(QList socketNotifiers, int nfds, fd_set *fdread, + fd_set *fdwrite, int timeout); +#endif // Q_OS_BLACKBERRY + // according to X/OPEN we have to define semun ourselves // we use prefix as on some systems sem.h will have it struct semid_ds;