diff options
| -rw-r--r-- | src/TcpSocket.cpp | 22 | ||||
| -rw-r--r-- | src/TcpSocket.h | 5 | ||||
| -rw-r--r-- | src/dabOutput/dabOutputTcp.cpp | 12 | 
3 files changed, 34 insertions, 5 deletions
| diff --git a/src/TcpSocket.cpp b/src/TcpSocket.cpp index b9824fa..40c1c1a 100644 --- a/src/TcpSocket.cpp +++ b/src/TcpSocket.cpp @@ -2,7 +2,7 @@     Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in     Right of Canada (Communications Research Center Canada) -   Copyright (C) 2016 +   Copyright (C) 2017     Matthias P. Braendli, matthias.braendli@mpb.li      http://www.opendigitalradio.org @@ -132,8 +132,26 @@ ssize_t TcpSocket::recv(void* data, size_t size)  } -ssize_t TcpSocket::send(const void* data, size_t size) +ssize_t TcpSocket::send(const void* data, size_t size, int timeout_ms)  { +    if (timeout_ms) { +        struct pollfd fds[1]; +        fds[0].fd = m_sock; +        fds[0].events = POLLOUT; + +        int retval = poll(fds, 1, timeout_ms); + +        if (retval == -1) { +            stringstream ss; +            ss << "TCP Socket send error on poll(): " << strerror(errno); +            throw std::runtime_error(ss.str()); +        } +        else if (retval == 0) { +            // Timed out +            return 0; +        } +    } +      /* Without MSG_NOSIGNAL the process would receive a SIGPIPE and die */      ssize_t ret = ::send(m_sock, (const char*)data, size, MSG_NOSIGNAL); diff --git a/src/TcpSocket.h b/src/TcpSocket.h index 660515d..9ff09e5 100644 --- a/src/TcpSocket.h +++ b/src/TcpSocket.h @@ -2,7 +2,7 @@     Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in     Right of Canada (Communications Research Center Canada) -   Copyright (C) 2016 +   Copyright (C) 2017     Matthias P. Braendli, matthias.braendli@mpb.li      http://www.opendigitalradio.org @@ -77,9 +77,10 @@ class TcpSocket          /** Send data over the TCP connection.           *  @param data The buffer that will be sent.           *  @param size Number of bytes to send. +         *  @param timeout_ms number of milliseconds before timeout           *  return number of bytes sent or -1 if error           */ -        ssize_t send(const void* data, size_t size); +        ssize_t send(const void* data, size_t size, int timeout_ms=0);          /** Receive data from the socket.           *  @param data The buffer that will receive data. diff --git a/src/dabOutput/dabOutputTcp.cpp b/src/dabOutput/dabOutputTcp.cpp index 2aab48a..f5aebe0 100644 --- a/src/dabOutput/dabOutputTcp.cpp +++ b/src/dabOutput/dabOutputTcp.cpp @@ -89,7 +89,17 @@ class TCPConnection                  queue.wait_and_pop(data);                  try { -                    m_sock.send(&data[0], data.size()); +                    ssize_t sent = 0; +                    do { +                        const int timeout_ms = 10; // Less than one ETI frame +                        sent = m_sock.send(&data[0], data.size(), timeout_ms); + +                        if (is_overloaded()) { +                            m_running = false; +                            break; +                        } +                    } +                    while (sent == 0);                  }                  catch (std::runtime_error& e) {                      m_running = false; | 
