summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Shienkov <denis.shienkov@gmail.com>2013-12-25 17:52:51 +0400
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-15 10:07:28 +0100
commitf404826e695c3affb684f3185d74cd3a5b31efbc (patch)
tree9c795ec28a93c2854b16733bc637d91b76f72c93
parentd5658bd0ced4a1eb0703d3cb1b566025d610fbdd (diff)
Unify of the internal API of asynchronous handling
It makes sense to unify internal methods of asynchronous I/O where to each method of start of operation corresponds the method of completion of operation: * startAsyncCommunication() - it is a new method which has a code relating to the handling of the WaitCommEvent() function. It implementations is taken directly by copy/paste with minimal modifications relating with adding of returns a boolean values. * _q_completeAsyncCommunication() - it is an existing method which is renamed from the _q_canCompleteCommunication(). * startAsyncRead() - it is an existing method without modifications. * _q_completeAsyncRead() - it is an existing method which is renamed from the _q_canCompleteRead(). Earlier this method contained a subfunction of the completeAsyncRead(DWORD) which is deleted now, and its code (related with the policy processing) is moved into body of the _q_completeAsyncRead() with the minimum modifications which do not change it behavior. * startAsyncWrite() - it is an existing method without modifications. * _q_completeAsyncWrite() - it is an existing method which is renamed from the _q_canCompleteWrite(). Earlier this method contained a subfunction of the completeAsyncWrite(DWORD) which is deleted now, and its code is moved into body of the _q_completeAsyncWrite() without modifications. Also in addition is added the new method emitReadyRead() and the code of policy emulation is moved into new method emulateErrorPolicy(). Change-Id: I58345e3270d676879a16efc4b7f35f74869894d8 Reviewed-by: Sergey Belyashov <Sergey.Belyashov@gmail.com> Reviewed-by: Denis Shienkov <denis.shienkov@gmail.com>
-rw-r--r--src/serialport/qserialport.h6
-rw-r--r--src/serialport/qserialport_win.cpp171
-rw-r--r--src/serialport/qserialport_win_p.h12
3 files changed, 94 insertions, 95 deletions
diff --git a/src/serialport/qserialport.h b/src/serialport/qserialport.h
index c07af91b..1689222b 100644
--- a/src/serialport/qserialport.h
+++ b/src/serialport/qserialport.h
@@ -276,9 +276,9 @@ private:
Q_DISABLE_COPY(QSerialPort)
#if defined (Q_OS_WIN32) || defined(Q_OS_WIN64)
- Q_PRIVATE_SLOT(d_func(), void _q_canCompleteCommunication())
- Q_PRIVATE_SLOT(d_func(), void _q_canCompleteRead())
- Q_PRIVATE_SLOT(d_func(), void _q_canCompleteWrite())
+ Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncCommunication())
+ Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncRead())
+ Q_PRIVATE_SLOT(d_func(), void _q_completeAsyncWrite())
#endif
};
diff --git a/src/serialport/qserialport_win.cpp b/src/serialport/qserialport_win.cpp
index e460c785..ecbfa393 100644
--- a/src/serialport/qserialport_win.cpp
+++ b/src/serialport/qserialport_win.cpp
@@ -115,7 +115,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
q->setError(decodeSystemError());
else {
communicationNotifier->setHandle(communicationOverlapped.hEvent);
- q->connect(communicationNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteCommunication()));
+ q->connect(communicationNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncCommunication()));
}
::ZeroMemory(&readCompletionOverlapped, sizeof(readCompletionOverlapped));
@@ -124,7 +124,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
q->setError(decodeSystemError());
else {
readCompletionNotifier->setHandle(readCompletionOverlapped.hEvent);
- q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteRead()));
+ q->connect(readCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncRead()));
}
::ZeroMemory(&writeCompletionOverlapped, sizeof(writeCompletionOverlapped));
@@ -133,7 +133,7 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
q->setError(decodeSystemError());
else {
writeCompletionNotifier->setHandle(writeCompletionOverlapped.hEvent);
- q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_canCompleteWrite()));
+ q->connect(writeCompletionNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_completeAsyncWrite()));
}
}
@@ -197,14 +197,8 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
return false;
}
- initializeOverlappedStructure(communicationOverlapped);
- if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) {
- const QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- q->setError(decodeSystemError());
- return false;
- }
- }
+ if (!startAsyncCommunication())
+ return false;
communicationNotifier->setEnabled(true);
@@ -393,14 +387,14 @@ bool QSerialPortPrivate::waitForReadyRead(int msecs)
}
if (triggeredEvent == communicationOverlapped.hEvent) {
- _q_canCompleteCommunication();
+ _q_completeAsyncCommunication();
if (error != QSerialPort::NoError)
return false;
} else if (triggeredEvent == readCompletionOverlapped.hEvent) {
- _q_canCompleteRead();
+ _q_completeAsyncRead();
return error == QSerialPort::NoError;
} else if (triggeredEvent == writeCompletionOverlapped.hEvent) {
- _q_canCompleteWrite();
+ _q_completeAsyncWrite();
} else {
return false;
}
@@ -431,11 +425,11 @@ bool QSerialPortPrivate::waitForBytesWritten(int msecs)
}
if (triggeredEvent == communicationOverlapped.hEvent) {
- _q_canCompleteRead();
+ _q_completeAsyncRead();
} else if (triggeredEvent == readCompletionOverlapped.hEvent) {
- _q_canCompleteRead();
+ _q_completeAsyncRead();
} else if (triggeredEvent == writeCompletionOverlapped.hEvent) {
- _q_canCompleteWrite();
+ _q_completeAsyncWrite();
return error == QSerialPort::NoError;
} else {
return false;
@@ -544,7 +538,7 @@ bool QSerialPortPrivate::setDataErrorPolicy(QSerialPort::DataErrorPolicy policy)
#ifndef Q_OS_WINCE
-void QSerialPortPrivate::_q_canCompleteCommunication()
+void QSerialPortPrivate::_q_completeAsyncCommunication()
{
Q_Q(QSerialPort);
@@ -576,7 +570,7 @@ void QSerialPortPrivate::_q_canCompleteCommunication()
startAsyncRead();
}
-void QSerialPortPrivate::_q_canCompleteRead()
+void QSerialPortPrivate::_q_completeAsyncRead()
{
Q_Q(QSerialPort);
@@ -584,23 +578,22 @@ void QSerialPortPrivate::_q_canCompleteRead()
if (!::GetOverlappedResult(descriptor, &readCompletionOverlapped, &numberOfBytesTransferred, FALSE))
q->setError(decodeSystemError());
- completeAsyncRead(numberOfBytesTransferred);
+ if (numberOfBytesTransferred > 0) {
+
+ readBuffer.append(readChunkBuffer.left(numberOfBytesTransferred));
+
+ if (!emulateErrorPolicy())
+ emitReadyRead();
+ }
// start async read for possible remainder into driver queue
- if ((numberOfBytesTransferred > 0) && (policy == QSerialPort::IgnorePolicy)) {
+ if ((numberOfBytesTransferred > 0) && (policy == QSerialPort::IgnorePolicy))
startAsyncRead();
- } else { // driver queue is emplty, so startup wait comm event
- initializeOverlappedStructure(communicationOverlapped);
- if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) {
- const QSerialPort::SerialPortError error = decodeSystemError();
- if (error != QSerialPort::NoError) {
- q->setError(decodeSystemError());
- }
- }
- }
+ else // driver queue is emplty, so startup wait comm event
+ startAsyncCommunication();
}
-void QSerialPortPrivate::_q_canCompleteWrite()
+void QSerialPortPrivate::_q_completeAsyncWrite()
{
Q_Q(QSerialPort);
@@ -610,7 +603,30 @@ void QSerialPortPrivate::_q_canCompleteWrite()
q->setError(decodeSystemError());
}
- completeAsyncWrite(numberOfBytesTransferred);
+ writeBuffer.free(numberOfBytesTransferred);
+
+ if (numberOfBytesTransferred > 0)
+ emit q->bytesWritten(numberOfBytesTransferred);
+
+ if (writeBuffer.isEmpty())
+ writeSequenceStarted = false;
+ else
+ startAsyncWrite();
+}
+
+bool QSerialPortPrivate::startAsyncCommunication()
+{
+ Q_Q(QSerialPort);
+
+ initializeOverlappedStructure(communicationOverlapped);
+ if (!::WaitCommEvent(descriptor, &triggeredEventMask, &communicationOverlapped)) {
+ const QSerialPort::SerialPortError error = decodeSystemError();
+ if (error != QSerialPort::NoError) {
+ q->setError(decodeSystemError());
+ return false;
+ }
+ }
+ return true;
}
bool QSerialPortPrivate::startAsyncRead()
@@ -675,6 +691,42 @@ bool QSerialPortPrivate::startAsyncWrite()
return true;
}
+bool QSerialPortPrivate::emulateErrorPolicy()
+{
+ if (!parityErrorOccurred)
+ return false;
+
+ parityErrorOccurred = false;
+
+ switch (policy) {
+ case QSerialPort::SkipPolicy:
+ readBuffer.getChar();
+ break;
+ case QSerialPort::PassZeroPolicy:
+ readBuffer.getChar();
+ readBuffer.putChar('\0');
+ emitReadyRead();
+ break;
+ case QSerialPort::IgnorePolicy:
+ return false;
+ case QSerialPort::StopReceivingPolicy:
+ emitReadyRead();
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+void QSerialPortPrivate::emitReadyRead()
+{
+ Q_Q(QSerialPort);
+
+ readyReadEmitted = true;
+ emit q->readyRead();
+}
+
#endif // #ifndef Q_OS_WINCE
void QSerialPortPrivate::processIoErrors(bool error)
@@ -706,61 +758,6 @@ void QSerialPortPrivate::processIoErrors(bool error)
#ifndef Q_OS_WINCE
-void QSerialPortPrivate::completeAsyncRead(DWORD numberOfBytes)
-{
- Q_Q(QSerialPort);
-
- if (numberOfBytes > 0) {
-
- readBuffer.append(readChunkBuffer.left(numberOfBytes));
-
- // Process emulate policy.
- if ((policy != QSerialPort::IgnorePolicy) && parityErrorOccurred) {
-
- parityErrorOccurred = false;
-
- // Ignore received character, remove it from buffer
- if (policy == QSerialPort::SkipPolicy) {
- readBuffer.getChar();
- // Force returning without emitting a readyRead() signal
- return;
- }
-
- // Abort receiving
- if (policy == QSerialPort::StopReceivingPolicy) {
- readyReadEmitted = true;
- emit q->readyRead();
- return;
- }
-
- // Replace received character by zero
- if (policy == QSerialPort::PassZeroPolicy) {
- readBuffer.getChar();
- readBuffer.putChar('\0');
- }
-
- }
-
- readyReadEmitted = true;
- emit q->readyRead();
- }
-}
-
-void QSerialPortPrivate::completeAsyncWrite(DWORD numberOfBytes)
-{
- Q_Q(QSerialPort);
-
- writeBuffer.free(numberOfBytes);
-
- if (numberOfBytes > 0)
- emit q->bytesWritten(numberOfBytes);
-
- if (writeBuffer.isEmpty())
- writeSequenceStarted = false;
- else
- startAsyncWrite();
-}
-
bool QSerialPortPrivate::updateDcb()
{
Q_Q(QSerialPort);
diff --git a/src/serialport/qserialport_win_p.h b/src/serialport/qserialport_win_p.h
index 61e6ce80..9876fe4b 100644
--- a/src/serialport/qserialport_win_p.h
+++ b/src/serialport/qserialport_win_p.h
@@ -96,14 +96,16 @@ public:
void processIoErrors(bool error);
QSerialPort::SerialPortError decodeSystemError() const;
#ifndef Q_OS_WINCE
- void _q_canCompleteCommunication();
- void _q_canCompleteRead();
- void _q_canCompleteWrite();
+ void _q_completeAsyncCommunication();
+ void _q_completeAsyncRead();
+ void _q_completeAsyncWrite();
+ bool startAsyncCommunication();
bool startAsyncRead();
bool startAsyncWrite();
- void completeAsyncRead(DWORD numberOfBytes);
- void completeAsyncWrite(DWORD numberOfBytes);
+
+ bool emulateErrorPolicy();
+ void emitReadyRead();
#else
bool notifyRead();
bool notifyWrite();