summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorFrank Schmirler <vdr@schmirler.de>2012-03-03 23:04:11 +0100
committerFrank Schmirler <vdr@schmirler.de>2012-03-03 23:39:30 +0100
commitc1dc1453c5e47b46a43a81e006ab34005b20526d (patch)
tree8159a8c92fcc725bca3881b4f4a19271bbe61e34 /tools
parenta047fc7d3245cfe924fb804c9c98634e634af5be (diff)
downloadvdr-plugin-streamdev-c1dc1453c5e47b46a43a81e006ab34005b20526d.tar.gz
vdr-plugin-streamdev-c1dc1453c5e47b46a43a81e006ab34005b20526d.tar.bz2
Added timeout to Commit()
Diffstat (limited to 'tools')
-rw-r--r--tools/socket.c34
-rw-r--r--tools/socket.h12
2 files changed, 36 insertions, 10 deletions
diff --git a/tools/socket.c b/tools/socket.c
index 5dde45a..2fc2c42 100644
--- a/tools/socket.c
+++ b/tools/socket.c
@@ -1,4 +1,5 @@
#include "tools/socket.h"
+#include "tools/select.h"
#include <vdr/tools.h>
#include <string.h>
@@ -27,7 +28,7 @@ cTBSocket::~cTBSocket() {
if (IsOpen()) Close();
}
-bool cTBSocket::Connect(const std::string &Host, unsigned int Port) {
+bool cTBSocket::Connect(const std::string &Host, unsigned int Port, unsigned int TimeoutMs) {
socklen_t len;
int socket;
@@ -45,13 +46,36 @@ bool cTBSocket::Connect(const std::string &Host, unsigned int Port) {
return false;
}
+ if (TimeoutMs > 0 && ::fcntl(socket, F_SETFL, O_NONBLOCK) == -1) {
+ ::close(socket);
+ return false;
+ }
+
m_RemoteAddr.sin_family = AF_INET;
m_RemoteAddr.sin_port = htons(Port);
m_RemoteAddr.sin_addr.s_addr = inet_addr(Host.c_str());
- if (::connect(socket, (struct sockaddr*)&m_RemoteAddr,
- sizeof(m_RemoteAddr)) == -1) {
- ::close(socket);
- return false;
+ if (::connect(socket, (struct sockaddr*)&m_RemoteAddr, sizeof(m_RemoteAddr)) == -1) {
+ if (TimeoutMs > 0 && errno == EINPROGRESS) {
+ int so_error;
+ socklen_t len = sizeof(so_error);
+ cTBSelect select;
+ select.Add(socket);
+ if (select.Select(TimeoutMs) == -1 ||
+ ::getsockopt(socket, SOL_SOCKET, SO_ERROR, &so_error, &len) == -1) {
+ ::close(socket);
+ return false;
+ }
+ if (so_error) {
+ errno = so_error;
+ ::close(socket);
+ return false;
+ }
+
+ }
+ else {
+ ::close(socket);
+ return false;
+ }
}
if (m_Type == SOCK_STREAM) {
diff --git a/tools/socket.h b/tools/socket.h
index 3dc7a33..effdef8 100644
--- a/tools/socket.h
+++ b/tools/socket.h
@@ -32,11 +32,13 @@ public:
Reimplemented for TCP/IPv4 sockets. */
virtual ssize_t SysWrite(const void *Buffer, size_t Length) const;
- /* Connect() tries to connect an available local socket to the port given
- by Port of the target host given by Host in numbers-and-dots notation
- (i.e. "212.43.45.21"). Returns true if the connection attempt was
- successful and false otherwise, setting errno appropriately. */
- virtual bool Connect(const std::string &Host, uint Port);
+ /* Connect() tries to connect an available local socket within TimeoutMs
+ milliseconds to the port given by Port of the target host given by
+ Host in numbers-and-dots notation (i.e. "212.43.45.21"). A TimeoutMs
+ of 0 will disable non-blocking IO for the connect call. Returns true
+ if the connection attempt was successful and false otherwise, setting
+ errno appropriately. */
+ virtual bool Connect(const std::string &Host, uint Port, uint TimeoutMs = 0);
/* Shutdown() shuts down one or both ends of a socket. If called with How
set to SHUT_RD, further reads on this socket will be denied. If called