diff options
author | Bernd Weimer <bweimer@rim.com> | 2012-10-25 10:53:35 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-10-26 20:49:01 +0200 |
commit | 9dacccd0391219c97c01e89f0547ee002abb1e55 (patch) | |
tree | b4cd67e92c782878c220d622a581fb1ebda683c4 /src/corelib/kernel/qeventdispatcher_unix.cpp | |
parent | 02dacc2c064339f557101db98bd40ace361e1bb6 (diff) |
Removed usage of pipe in Blackberry event dispatcher
Using a pipe for thread wake-ups is inefficient and can introduce significant
latency. Replaced the pipe by directly sending a BPS event.
Refactored the wake-up code in the private class of the UNIX event dispatcher.
Change-Id: Ic073b0b56c3cbf8327fc6bc3c37132cc3583ef86
Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
Diffstat (limited to 'src/corelib/kernel/qeventdispatcher_unix.cpp')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_unix.cpp | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 44715b0553..6c2a610a56 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -110,7 +110,7 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() bool pipefail = false; // initialize the common parts of the event loop -#if defined(Q_OS_NACL) +#if defined(Q_OS_NACL) || defined (Q_OS_BLACKBERRY) // do nothing. #elif defined(Q_OS_INTEGRITY) // INTEGRITY doesn't like a "select" on pipes, so use socketpair instead @@ -157,7 +157,7 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() { -#if defined(Q_OS_NACL) +#if defined(Q_OS_NACL) || defined (Q_OS_BLACKBERRY) // do nothing. #elif defined(Q_OS_VXWORKS) close(thread_pipe[0]); @@ -211,8 +211,8 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, FD_ZERO(&sn_vec[2].select_fds); } - FD_SET(thread_pipe[0], &sn_vec[0].select_fds); - highest = qMax(highest, thread_pipe[0]); + int wakeUpFd = initThreadWakeUp(); + highest = qMax(highest, wakeUpFd); nsel = q->select(highest + 1, &sn_vec[0].select_fds, @@ -271,25 +271,7 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, } } - // some other thread woke us up... consume the data on the thread pipe so that - // select doesn't immediately return next time - int nevents = 0; - if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) { -#if defined(Q_OS_VXWORKS) - char c[16]; - ::read(thread_pipe[0], c, sizeof(c)); - ::ioctl(thread_pipe[0], FIOFLUSH, 0); -#else - char c[16]; - while (::read(thread_pipe[0], c, sizeof(c)) > 0) - ; -#endif - if (!wakeUps.testAndSetRelease(1, 0)) { - // hopefully, this is dead code - qWarning("QEventDispatcherUNIX: internal error, wakeUps.testAndSetRelease(1, 0) failed!"); - } - ++nevents; - } + int nevents = processThreadWakeUp(nsel); // activate socket notifiers if (! (flags & QEventLoop::ExcludeSocketNotifiers) && nsel > 0 && sn_highest >= 0) { @@ -307,6 +289,35 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, return (nevents + q->activateSocketNotifiers()); } +int QEventDispatcherUNIXPrivate::initThreadWakeUp() +{ + FD_SET(thread_pipe[0], &sn_vec[0].select_fds); + return thread_pipe[0]; +} + +int QEventDispatcherUNIXPrivate::processThreadWakeUp(int nsel) +{ + if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) { + // some other thread woke us up... consume the data on the thread pipe so that + // select doesn't immediately return next time +#if defined(Q_OS_VXWORKS) + char c[16]; + ::read(thread_pipe[0], c, sizeof(c)); + ::ioctl(thread_pipe[0], FIOFLUSH, 0); +#else + char c[16]; + while (::read(thread_pipe[0], c, sizeof(c)) > 0) + ; +#endif + if (!wakeUps.testAndSetRelease(1, 0)) { + // hopefully, this is dead code + qWarning("QEventDispatcherUNIX: internal error, wakeUps.testAndSetRelease(1, 0) failed!"); + } + return 1; + } + return 0; +} + QEventDispatcherUNIX::QEventDispatcherUNIX(QObject *parent) : QAbstractEventDispatcher(*new QEventDispatcherUNIXPrivate, parent) { } |