From 794afe9a1b5ee36a5de8f90f3d789ca46f393bb7 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Mon, 15 Oct 2012 11:48:14 +0200 Subject: [PATCH] Added support for timeout when receiving data from a socket (POSIX platform). --- src/platforms/posix/posixSocket.cpp | 50 ++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/platforms/posix/posixSocket.cpp b/src/platforms/posix/posixSocket.cpp index b8bb8b18..f280dadc 100644 --- a/src/platforms/posix/posixSocket.cpp +++ b/src/platforms/posix/posixSocket.cpp @@ -336,7 +336,45 @@ void posixSocket::receive(vmime::string& buffer) posixSocket::size_type posixSocket::receiveRaw(char* buffer, const size_type count) { - const int ret = ::recv(m_desc, buffer, count, 0); + // Check whether data is available + fd_set fds; + FD_ZERO(&fds); + FD_SET(m_desc, &fds); + + struct timeval tv; + tv.tv_sec = 1; + tv.tv_usec = 0; + + int ret = ::select(m_desc + 1, &fds, NULL, NULL, &tv); + + if (ret < 0) + { + if (errno != EAGAIN) + throwSocketError(errno); + + // No data available at this time + // Check if we are timed out + if (m_timeoutHandler && + m_timeoutHandler->isTimeOut()) + { + if (!m_timeoutHandler->handleTimeOut()) + { + // Server did not react within timeout delay + throwSocketError(errno); + } + else + { + // Reset timeout + m_timeoutHandler->resetTimeOut(); + } + } + + // Continue waiting for data + return 0; + } + + // Read available data + ret = ::recv(m_desc, buffer, count, 0); if (ret < 0) { @@ -351,6 +389,12 @@ posixSocket::size_type posixSocket::receiveRaw(char* buffer, const size_type cou // Host shutdown throwSocketError(ENOTCONN); } + else + { + // Data received, reset timeout + if (m_timeoutHandler) + m_timeoutHandler->resetTimeOut(); + } return ret; } @@ -383,6 +427,10 @@ void posixSocket::sendRaw(const char* buffer, const size_type count) size -= ret; } } + + // Reset timeout + if (m_timeoutHandler) + m_timeoutHandler->resetTimeOut(); }