diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-02-14 15:07:11 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-02-14 15:07:26 +0100 |
commit | 12fa79ed9783320eceee7d49a656245e64cdb10e (patch) | |
tree | 2d8184db0612b1c9ceef79dfb00d68232a8f74dc | |
parent | b240d198f80e47c484f1c22d259da85227421950 (diff) | |
parent | 21f50498f7558e59bca8789e94c0fe5d14a9e27d (diff) | |
download | qtserialport-12fa79ed9783320eceee7d49a656245e64cdb10e.tar.gz |
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: I111ca7fd67979152329f290d45bd5b47551a404a
-rw-r--r-- | src/serialport/qserialport_unix.cpp | 73 | ||||
-rw-r--r-- | src/serialport/qserialport_unix_p.h | 6 |
2 files changed, 46 insertions, 33 deletions
diff --git a/src/serialport/qserialport_unix.cpp b/src/serialport/qserialport_unix.cpp index 84f3109..d99575f 100644 --- a/src/serialport/qserialport_unix.cpp +++ b/src/serialport/qserialport_unix.cpp @@ -59,8 +59,6 @@ #include <QtCore/qsocketnotifier.h> #include <QtCore/qmap.h> -#include <private/qcore_unix_p.h> - QT_BEGIN_NAMESPACE QString serialPortLockFilePath(const QString &portName) @@ -135,7 +133,7 @@ protected: bool event(QEvent *e) Q_DECL_OVERRIDE { bool ret = QSocketNotifier::event(e); if (ret) - dptr->writeNotification(); + dptr->completeAsyncWrite(); return ret; } @@ -178,6 +176,8 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q) , readPortNotifierStateSet(false) , emittedReadyRead(false) , emittedBytesWritten(false) + , pendingBytesWritten(0) + , writeSequenceStarted(false) { } @@ -215,7 +215,7 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode) break; } - descriptor = qt_safe_open(systemLocation.toLocal8Bit().constData(), flags); + descriptor = ::open(systemLocation.toLocal8Bit().constData(), flags); if (descriptor == -1) { q->setError(decodeSystemError()); @@ -306,7 +306,7 @@ void QSerialPortPrivate::close() exceptionNotifier = 0; } - if (qt_safe_close(descriptor) == -1) + if (::close(descriptor) == -1) q->setError(decodeSystemError()); if (lockFileScopedPointer->isLocked()) @@ -314,6 +314,8 @@ void QSerialPortPrivate::close() descriptor = -1; isCustomBaudRateSupported = false; + pendingBytesWritten = 0; + writeSequenceStarted = false; } QSerialPort::PinoutSignals QSerialPortPrivate::pinoutSignals() @@ -403,7 +405,7 @@ bool QSerialPortPrivate::setRequestToSend(bool set) bool QSerialPortPrivate::flush() { - return writeNotification() + return startAsyncWrite() #ifndef Q_OS_ANDROID && (::tcdrain(descriptor) != -1); #else @@ -479,7 +481,7 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs) } if (readyToWrite) - writeNotification(); + completeAsyncWrite(); } while (msecs == -1 || timeoutValue(msecs, stopWatch.elapsed()) > 0); return false; @@ -489,7 +491,7 @@ bool QSerialPortPrivate::waitForBytesWritten(int msecs) { Q_Q(QSerialPort); - if (writeBuffer.isEmpty()) + if (writeBuffer.isEmpty() && pendingBytesWritten <= 0) return false; QElapsedTimer stopWatch; @@ -511,7 +513,7 @@ bool QSerialPortPrivate::waitForBytesWritten(int msecs) return false; if (readyToWrite) - return writeNotification(); + return completeAsyncWrite(); } return false; } @@ -790,23 +792,15 @@ bool QSerialPortPrivate::readNotification() return true; } -bool QSerialPortPrivate::writeNotification() +bool QSerialPortPrivate::startAsyncWrite() { Q_Q(QSerialPort); - const int tmp = writeBuffer.size(); - - if (writeBuffer.isEmpty()) { - setWriteNotificationEnabled(false); - return false; - } - - int nextSize = writeBuffer.nextDataBlockSize(); - - const char *ptr = writeBuffer.readPointer(); + if (writeBuffer.isEmpty() || writeSequenceStarted) + return true; // Attempt to write it all in one chunk. - qint64 written = writeToPort(ptr, nextSize); + qint64 written = writeToPort(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize()); if (written < 0) { QSerialPort::SerialPortError error = decodeSystemError(); if (error != QSerialPort::ResourceError) @@ -815,21 +809,36 @@ bool QSerialPortPrivate::writeNotification() return false; } - // Remove what we wrote so far. writeBuffer.free(written); - if (written > 0) { - // Don't emit bytesWritten() recursively. + pendingBytesWritten += written; + writeSequenceStarted = true; + + if (!isWriteNotificationEnabled()) + setWriteNotificationEnabled(true); + return true; +} + +bool QSerialPortPrivate::completeAsyncWrite() +{ + Q_Q(QSerialPort); + + if (pendingBytesWritten > 0) { if (!emittedBytesWritten) { emittedBytesWritten = true; - emit q->bytesWritten(written); + emit q->bytesWritten(pendingBytesWritten); + pendingBytesWritten = 0; emittedBytesWritten = false; } } - if (writeBuffer.isEmpty()) + writeSequenceStarted = false; + + if (writeBuffer.isEmpty()) { setWriteNotificationEnabled(false); + return true; + } - return (writeBuffer.size() < tmp); + return startAsyncWrite(); } void QSerialPortPrivate::exceptionNotification() @@ -1078,7 +1087,7 @@ qint64 QSerialPortPrivate::readFromPort(char *data, qint64 maxSize) if (parity != QSerialPort::MarkParity && parity != QSerialPort::SpaceParity) { #endif - bytesRead = qt_safe_read(descriptor, data, maxSize); + bytesRead = ::read(descriptor, data, maxSize); } else {// Perform parity emulation. bytesRead = readPerChar(data, maxSize); } @@ -1090,11 +1099,11 @@ qint64 QSerialPortPrivate::writeToPort(const char *data, qint64 maxSize) { qint64 bytesWritten = 0; #if defined (CMSPAR) - bytesWritten = qt_safe_write(descriptor, data, maxSize); + bytesWritten = ::write(descriptor, data, maxSize); #else if (parity != QSerialPort::MarkParity && parity != QSerialPort::SpaceParity) { - bytesWritten = qt_safe_write(descriptor, data, maxSize); + bytesWritten = ::write(descriptor, data, maxSize); } else {// Perform parity emulation. bytesWritten = writePerChar(data, maxSize); } @@ -1131,7 +1140,7 @@ qint64 QSerialPortPrivate::writePerChar(const char *data, qint64 maxSize) break; } - int r = qt_safe_write(descriptor, data, 1); + int r = ::write(descriptor, data, 1); if (r < 0) return -1; if (r > 0) { @@ -1157,7 +1166,7 @@ qint64 QSerialPortPrivate::readPerChar(char *data, qint64 maxSize) int prefix = 0; while (ret < maxSize) { - qint64 r = qt_safe_read(descriptor, data, 1); + qint64 r = ::read(descriptor, data, 1); if (r < 0) { if (errno == EAGAIN) // It is ok for nonblocking mode. break; diff --git a/src/serialport/qserialport_unix_p.h b/src/serialport/qserialport_unix_p.h index 1960316..ed86fc8 100644 --- a/src/serialport/qserialport_unix_p.h +++ b/src/serialport/qserialport_unix_p.h @@ -121,7 +121,8 @@ public: bool setDataErrorPolicy(QSerialPort::DataErrorPolicy policy); bool readNotification(); - bool writeNotification(); + bool startAsyncWrite(); + bool completeAsyncWrite(); void exceptionNotification(); static QString portNameToSystemLocation(const QString &port); @@ -152,6 +153,9 @@ public: bool emittedReadyRead; bool emittedBytesWritten; + qint64 pendingBytesWritten; + bool writeSequenceStarted; + QScopedPointer<QLockFile> lockFileScopedPointer; private: |