From 9dacccd0391219c97c01e89f0547ee002abb1e55 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Thu, 25 Oct 2012 10:53:35 +0200 Subject: 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 Reviewed-by: Thiago Macieira Reviewed-by: Rafael Roquetto --- src/corelib/kernel/qeventdispatcher_unix.cpp | 57 +++++++++++++++++----------- 1 file changed, 34 insertions(+), 23 deletions(-) (limited to 'src/corelib/kernel/qeventdispatcher_unix.cpp') 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) { } -- cgit v1.2.3