From 5347b94bbd7455453754fd79b6aaa64aa368ce59 Mon Sep 17 00:00:00 2001 From: Lars Op den Kamp Date: Thu, 29 Mar 2012 11:53:41 +0200 Subject: [PATCH] win32: implemented timeouts in serial socket reads --- src/lib/platform/sockets/serialport.h | 6 ++++ src/lib/platform/windows/os-socket.h | 2 ++ src/lib/platform/windows/serialport.cpp | 38 +++++++++++++++---------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/lib/platform/sockets/serialport.h b/src/lib/platform/sockets/serialport.h index bdd05b9..fb4be19 100644 --- a/src/lib/platform/sockets/serialport.h +++ b/src/lib/platform/sockets/serialport.h @@ -71,6 +71,9 @@ namespace PLATFORM public: CSerialSocket(const CStdString &strName, uint32_t iBaudrate, SerialDataBits iDatabits = SERIAL_DATA_BITS_EIGHT, SerialStopBits iStopbits = SERIAL_STOP_BITS_ONE, SerialParity iParity = SERIAL_PARITY_NONE) : CCommonSocket(INVALID_SERIAL_SOCKET_VALUE, strName), +#ifdef __WINDOWS__ + m_iCurrentTimeout(0), +#endif m_bIsOpen(false), m_iBaudrate(iBaudrate), m_iDatabits(iDatabits), @@ -96,6 +99,9 @@ namespace PLATFORM protected: #ifndef __WINDOWS__ struct termios m_options; + #else + bool SetTimeouts(serial_socket_t socket, int* iError, DWORD iTimeout); + DWORD m_iCurrentTimeout; #endif bool m_bIsOpen; diff --git a/src/lib/platform/windows/os-socket.h b/src/lib/platform/windows/os-socket.h index 5174cba..86750c5 100644 --- a/src/lib/platform/windows/os-socket.h +++ b/src/lib/platform/windows/os-socket.h @@ -95,6 +95,8 @@ namespace PLATFORM inline ssize_t SerialSocketRead(serial_socket_t socket, int *iError, void* data, size_t len, uint64_t iTimeoutMs /*= 0*/) { + *iError = 0; + if (len != (DWORD)len) { *iError = EINVAL; diff --git a/src/lib/platform/windows/serialport.cpp b/src/lib/platform/windows/serialport.cpp index c0cdd93..fe91725 100644 --- a/src/lib/platform/windows/serialport.cpp +++ b/src/lib/platform/windows/serialport.cpp @@ -48,11 +48,14 @@ void FormatWindowsError(int iErrorCode, CStdString &strMessage) } } -bool SetTimeouts(serial_socket_t socket, int* iError, bool bBlocking) +bool CSerialSocket::SetTimeouts(serial_socket_t socket, int* iError, DWORD iTimeout) { if (socket == INVALID_HANDLE_VALUE) return false; + if (iTimeout == m_iCurrentTimeout) + return true; + COMMTIMEOUTS cto; if (!GetCommTimeouts(socket, &cto)) { @@ -60,18 +63,9 @@ bool SetTimeouts(serial_socket_t socket, int* iError, bool bBlocking) return false; } - if (bBlocking) - { - cto.ReadIntervalTimeout = 0; - cto.ReadTotalTimeoutConstant = 0; - cto.ReadTotalTimeoutMultiplier = 0; - } - else - { - cto.ReadIntervalTimeout = MAXDWORD; - cto.ReadTotalTimeoutConstant = 0; - cto.ReadTotalTimeoutMultiplier = 0; - } + cto.ReadIntervalTimeout = 0; + cto.ReadTotalTimeoutConstant = iTimeout; + cto.ReadTotalTimeoutMultiplier = 0; if (!SetCommTimeouts(socket, &cto)) { @@ -79,6 +73,7 @@ bool SetTimeouts(serial_socket_t socket, int* iError, bool bBlocking) return false; } + m_iCurrentTimeout = iTimeout; return true; } @@ -103,7 +98,20 @@ ssize_t CSerialSocket::Write(void* data, size_t len) ssize_t CSerialSocket::Read(void* data, size_t len, uint64_t iTimeoutMs /* = 0 */) { - return IsOpen() ? SerialSocketRead(m_socket, &m_iError, data, len, iTimeoutMs) : -1; + if (IsOpen()) + { + DWORD iTimeout((DWORD)iTimeoutMs); + if (iTimeout != iTimeoutMs) + return -1; + + int iError(0); + if (!SetTimeouts(m_socket, &iError, iTimeout)) + return -1; + + return SerialSocketRead(m_socket, &m_iError, data, len, iTimeoutMs); + } + + return -1; } bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */) @@ -153,7 +161,7 @@ bool CSerialSocket::Open(uint64_t iTimeoutMs /* = 0 */) return false; } - if (!SetTimeouts(m_socket, &m_iError, false)) + if (!SetTimeouts(m_socket, &m_iError, MAXDWORD)) { m_strError = "unable to set timeouts"; FormatWindowsError(GetLastError(), m_strError); -- 2.34.1