summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qeventdispatcher_unix.cpp
diff options
context:
space:
mode:
authorBernd Weimer <bweimer@rim.com>2012-10-25 10:53:35 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-10-26 20:49:01 +0200
commit9dacccd0391219c97c01e89f0547ee002abb1e55 (patch)
treeb4cd67e92c782878c220d622a581fb1ebda683c4 /src/corelib/kernel/qeventdispatcher_unix.cpp
parent02dacc2c064339f557101db98bd40ace361e1bb6 (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.cpp57
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)
{ }