diff options
author | Robin Burchell <robin.burchell@jollamobile.com> | 2014-01-22 11:49:16 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-24 20:54:52 +0100 |
commit | a4e703764e5f174fc6ca3f919e3acf44203dad91 (patch) | |
tree | 8302a2cc776245e98d3e239a34361348fff499b4 | |
parent | ac2988477204c4efe5d4b60de89270bade35dde1 (diff) | |
download | qtbase-a4e703764e5f174fc6ca3f919e3acf44203dad91.tar.gz qtbase-a4e703764e5f174fc6ca3f919e3acf44203dad91.tar.bz2 qtbase-a4e703764e5f174fc6ca3f919e3acf44203dad91.zip |
evdevtouch: Don't try to keep reading on EAGAIN
This stops touching the screen (and not moving) consuming 80-90% CPU.
The mtdev and non-mtdev codepaths have been separated for additional clarity.
Change-Id: I0559a6bd80dab961fdb4a83ad50860a9aec6445c
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
-rw-r--r-- | src/platformsupport/input/evdevtouch/qevdevtouch.cpp | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp index 81746974c5..b4ebf8179c 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouch.cpp +++ b/src/platformsupport/input/evdevtouch/qevdevtouch.cpp @@ -345,40 +345,61 @@ QEvdevTouchScreenHandler::~QEvdevTouchScreenHandler() void QEvdevTouchScreenHandler::readData() { ::input_event buffer[32]; - int n = 0; - for (; ;) { + int events = 0; + #if !defined(QT_NO_MTDEV) - int result = mtdev_get(m_mtdev, m_fd, buffer, sizeof(buffer) / sizeof(::input_event)); - if (result > 0) - result *= sizeof(::input_event); + forever { + do { + events = mtdev_get(m_mtdev, m_fd, buffer, sizeof(buffer) / sizeof(::input_event)); + // keep trying mtdev_get if we get interrupted. note that we do not + // (and should not) handle EAGAIN; EAGAIN means that reading would + // block and we'll get back here later to try again anyway. + } while (events == -1 && errno == EINTR); + + // 0 events is EOF, -1 means error, handle both in the same place + if (events <= 0) + goto err; + + // process our shiny new events + for (int i = 0; i < events; ++i) + d->processInputEvent(&buffer[i]); + + // and try to get more + } #else - int result = QT_READ(m_fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n); -#endif - if (!result) { - qWarning("evdevtouch: Got EOF from input device"); - return; - } else if (result < 0) { - if (errno != EINTR && errno != EAGAIN) { - qErrnoWarning(errno, "evdevtouch: Could not read from input device"); - if (errno == ENODEV) { // device got disconnected -> stop reading - delete m_notify; - m_notify = 0; - QT_CLOSE(m_fd); - m_fd = -1; - } - return; - } - } else { - n += result; - if (n % sizeof(::input_event) == 0) - break; - } + int n = 0; + for (; ;) { + events = QT_READ(m_fd, reinterpret_cast<char*>(buffer) + n, sizeof(buffer) - n); + if (events <= 0) + goto err; + n += events; + if (n % sizeof(::input_event) == 0) + break; } n /= sizeof(::input_event); for (int i = 0; i < n; ++i) d->processInputEvent(&buffer[i]); +#endif + return; + +err: + if (!events) { + qWarning("evdevtouch: Got EOF from input device"); + return; + } else if (events < 0) { + if (errno != EINTR && errno != EAGAIN) { + qErrnoWarning(errno, "evdevtouch: Could not read from input device"); + if (errno == ENODEV) { // device got disconnected -> stop reading + delete m_notify; + m_notify = 0; + QT_CLOSE(m_fd); + m_fd = -1; + } + return; + } + } } void QEvdevTouchScreenData::addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates) |