summaryrefslogtreecommitdiff
path: root/cppe/src/TcpTransport/Transceiver.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2006-02-20 10:31:57 +0000
committerBenoit Foucher <benoit@zeroc.com>2006-02-20 10:31:57 +0000
commite1d3d16e0fb475d771fbc476a3f1e88c9bcdc10f (patch)
tree03017261521ec7c308e3e092b15a74edcd6ca8e2 /cppe/src/TcpTransport/Transceiver.cpp
parentporting new proxy methods for connection mgmt (diff)
downloadice-e1d3d16e0fb475d771fbc476a3f1e88c9bcdc10f.tar.bz2
ice-e1d3d16e0fb475d771fbc476a3f1e88c9bcdc10f.tar.xz
ice-e1d3d16e0fb475d771fbc476a3f1e88c9bcdc10f.zip
Use socket timeouts by default.
Diffstat (limited to 'cppe/src/TcpTransport/Transceiver.cpp')
-rw-r--r--cppe/src/TcpTransport/Transceiver.cpp318
1 files changed, 181 insertions, 137 deletions
diff --git a/cppe/src/TcpTransport/Transceiver.cpp b/cppe/src/TcpTransport/Transceiver.cpp
index ee8a61f4744..3481f20239b 100644
--- a/cppe/src/TcpTransport/Transceiver.cpp
+++ b/cppe/src/TcpTransport/Transceiver.cpp
@@ -39,7 +39,7 @@ IceInternal::Transceiver::close()
out << "closing tcp connection\n" << toString();
}
-#ifndef ICEE_USE_SOCKET_TIMEOUT
+#ifdef ICEE_USE_SOCKET_TIMEOUT
#ifdef _WIN32
assert(_event != 0);
WSACloseEvent(_event);
@@ -93,8 +93,6 @@ IceInternal::Transceiver::shutdownReadWrite()
void
IceInternal::Transceiver::write(Buffer& buf, int timeout)
{
- assert(timeout != 0);
-
Buffer::Container::difference_type packetSize =
static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
@@ -108,81 +106,99 @@ IceInternal::Transceiver::write(Buffer& buf, int timeout)
}
#endif
- while(buf.i != buf.b.end())
+#ifndef ICEE_USE_SELECT_FOR_TIMEOUTS
+ if(timeout > 0 && timeout != _timeout)
{
-#if defined(ICEE_USE_SOCKET_TIMEOUT)
setTimeout(_fd, false, timeout);
-#elif !defined(_WIN32)
- if(timeout > 0)
- {
- doSelect(false, timeout);
- }
-#endif
-
- repeatSend:
- assert(_fd != INVALID_SOCKET);
- ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&*buf.i), packetSize, 0);
+ }
- if(ret == 0)
+ try
+ {
+#endif
+ while(buf.i != buf.b.end())
{
- ConnectionLostException ex(__FILE__, __LINE__);
- ex.error = 0;
- throw ex;
- }
+ repeatSend:
+ assert(_fd != INVALID_SOCKET);
+ ssize_t ret = ::send(_fd, reinterpret_cast<const char*>(&*buf.i), packetSize, 0);
- if(ret == SOCKET_ERROR)
- {
- if(interrupted())
+ if(ret == 0)
{
- goto repeatSend;
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = 0;
+ throw ex;
}
- if(noBuffers() && packetSize > 1024)
+ if(ret == SOCKET_ERROR)
{
- packetSize /= 2;
- goto repeatSend;
- }
+ if(interrupted())
+ {
+ goto repeatSend;
+ }
+
+ if(noBuffers() && packetSize > 1024)
+ {
+ packetSize /= 2;
+ goto repeatSend;
+ }
-#if defined(ICEE_USE_SOCKET_TIMEOUT)
- if(wouldBlock())
- {
- throw TimeoutException(__FILE__, __LINE__);
- }
-#elif defined(_WIN32)
- if(wouldBlock())
- {
- doSelect(false, timeout);
- continue;
- }
+#ifndef ICEE_USE_SELECT_FOR_TIMEOUTS
+ if(wouldBlock())
+ {
+ throw TimeoutException(__FILE__, __LINE__);
+ }
+#else
+ if(wouldBlock())
+ {
+ doSelect(false, timeout > 0 ? timeout : _timeout);
+ continue;
+ }
#endif
- if(connectionLost())
- {
- ConnectionLostException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
+ if(connectionLost())
+ {
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
}
- else
+
+ if(_traceLevels->network >= 3)
{
- SocketException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
+ Trace out(_logger, _traceLevels->networkCat);
+ out << Ice::printfToString("sent %d of %d", ret, packetSize) << " bytes via tcp\n" << toString();
}
- }
- if(_traceLevels->network >= 3)
- {
- Trace out(_logger, _traceLevels->networkCat);
- out << Ice::printfToString("sent %d of %d", ret, packetSize) << " bytes via tcp\n" << toString();
- }
+ buf.i += ret;
- buf.i += ret;
-
- if(packetSize > buf.b.end() - buf.i)
+ if(packetSize > buf.b.end() - buf.i)
+ {
+ packetSize = static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
+ }
+ }
+#ifndef ICEE_USE_SELECT_FOR_TIMEOUTS
+ }
+ catch(const Ice::LocalException&)
+ {
+ if(timeout > 0 && timeout != _timeout)
{
- packetSize = static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
+ try
+ {
+ setTimeout(_fd, false, _timeout);
+ }
+ catch(const Ice::LocalException&)
+ {
+ // IGNORE
+ }
}
+ throw;
}
+#endif
}
void
@@ -191,102 +207,119 @@ IceInternal::Transceiver::read(Buffer& buf, int timeout)
assert(timeout != 0);
Buffer::Container::difference_type packetSize =
- static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
-
- while(buf.i != buf.b.end())
+ static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
+
+#ifndef ICEE_USE_SELECT_FOR_TIMEOUTS
+ if(timeout > 0 && timeout != _timeout)
{
-#if defined(ICEE_USE_SOCKET_TIMEOUT)
setTimeout(_fd, true, timeout);
-#elif !defined(_WIN32)
- if(timeout > 0)
- {
- doSelect(true, timeout);
- }
+ }
+ try
+ {
#endif
-
- repeatRead:
- assert(_fd != INVALID_SOCKET);
- ssize_t ret = ::recv(_fd, reinterpret_cast<char*>(&*buf.i), packetSize, 0);
-
- if(ret == 0)
+ while(buf.i != buf.b.end())
{
- //
- // If the connection is lost when reading data, we shut
- // down the write end of the socket. This helps to unblock
- // threads that are stuck in send() or select() while
- // sending data. Note: I don't really understand why
- // send() or select() sometimes don't detect a connection
- // loss. Therefore this helper to make them detect it.
- //
- //assert(_fd != INVALID_SOCKET);
- //shutdownSocketReadWrite(_fd);
+ repeatRead:
+ assert(_fd != INVALID_SOCKET);
+ ssize_t ret = ::recv(_fd, reinterpret_cast<char*>(&*buf.i), packetSize, 0);
- ConnectionLostException ex(__FILE__, __LINE__);
- ex.error = 0;
- throw ex;
- }
-
- if(ret == SOCKET_ERROR)
- {
- if(interrupted())
+ if(ret == 0)
{
- goto repeatRead;
+ //
+ // If the connection is lost when reading data, we shut
+ // down the write end of the socket. This helps to unblock
+ // threads that are stuck in send() or select() while
+ // sending data. Note: I don't really understand why
+ // send() or select() sometimes don't detect a connection
+ // loss. Therefore this helper to make them detect it.
+ //
+ //assert(_fd != INVALID_SOCKET);
+ //shutdownSocketReadWrite(_fd);
+
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = 0;
+ throw ex;
}
- if(noBuffers() && packetSize > 1024)
+ if(ret == SOCKET_ERROR)
{
- packetSize /= 2;
- goto repeatRead;
+ if(interrupted())
+ {
+ goto repeatRead;
+ }
+
+ if(noBuffers() && packetSize > 1024)
+ {
+ packetSize /= 2;
+ goto repeatRead;
+ }
+
+#ifndef ICEE_USE_SELECT_FOR_TIMEOUTS
+ if(wouldBlock())
+ {
+ throw TimeoutException(__FILE__, __LINE__);
+ }
+#else
+ if(wouldBlock())
+ {
+ doSelect(true, timeout > 0 ? timeout : _timeout);
+ continue;
+ }
+#endif
+
+ if(connectionLost())
+ {
+ //
+ // See the commment above about shutting down the
+ // socket if the connection is lost while reading
+ // data.
+ //
+ //assert(_fd != INVALID_SOCKET);
+ //shutdownSocketReadWrite(_fd);
+
+ ConnectionLostException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
}
-
-#if defined(ICEE_USE_SOCKET_TIMEOUT)
- if(wouldBlock())
+
+ if(_traceLevels->network >= 3)
{
- throw TimeoutException(__FILE__, __LINE__);
+ Trace out(_logger, _traceLevels->networkCat);
+ out << Ice::printfToString("received %d of %d", ret, packetSize) << " bytes via tcp\n" << toString();
}
-#elif defined(_WIN32)
- if(wouldBlock())
+
+ buf.i += ret;
+
+ if(packetSize > buf.b.end() - buf.i)
{
- doSelect(true, timeout);
- continue;
+ packetSize = static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
}
-#endif
-
- if(connectionLost())
+ }
+#ifndef ICEE_USE_SELECT_FOR_TIMEOUTS
+ }
+ catch(const Ice::LocalException&)
+ {
+ if(timeout > 0 && timeout != _timeout)
+ {
+ try
{
- //
- // See the commment above about shutting down the
- // socket if the connection is lost while reading
- // data.
- //
- //assert(_fd != INVALID_SOCKET);
- //shutdownSocketReadWrite(_fd);
-
- ConnectionLostException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
+ setTimeout(_fd, true, _timeout);
}
- else
+ catch(const Ice::LocalException&)
{
- SocketException ex(__FILE__, __LINE__);
- ex.error = getSocketErrno();
- throw ex;
+ // IGNORE
}
}
-
- if(_traceLevels->network >= 3)
- {
- Trace out(_logger, _traceLevels->networkCat);
- out << Ice::printfToString("received %d of %d", ret, packetSize) << " bytes via tcp\n" << toString();
- }
-
- buf.i += ret;
-
- if(packetSize > buf.b.end() - buf.i)
- {
- packetSize = static_cast<Buffer::Container::difference_type>(buf.b.end() - buf.i);
- }
+ throw;
}
+#endif
}
string
@@ -301,16 +334,25 @@ IceInternal::Transceiver::toString() const
return _desc;
}
-IceInternal::Transceiver::Transceiver(const InstancePtr& instance, SOCKET fd) :
+IceInternal::Transceiver::Transceiver(const InstancePtr& instance, SOCKET fd, int timeout) :
_traceLevels(instance->traceLevels()),
_logger(instance->logger()),
_fd(fd),
+#ifndef ICEE_USE_SELECT_FOR_TIMEOUTS
+ _timeout(timeout),
+#endif
_desc(fdToString(fd))
#ifdef _WIN32
, _isPeerLocal(isPeerLocal(fd))
#endif
{
-#ifndef ICEE_USE_SOCKET_TIMEOUT
+#ifndef ICEE_USE_SELECT_FOR_TIMEOUTS
+ if(_timeout > 0)
+ {
+ setTimeout(_fd, false, _timeout);
+ setTimeout(_fd, true, _timeout);
+ }
+#else
#ifdef _WIN32
_event = WSACreateEvent();
_readEvent = WSACreateEvent();
@@ -363,7 +405,7 @@ IceInternal::Transceiver::Transceiver(const InstancePtr& instance, SOCKET fd) :
IceInternal::Transceiver::~Transceiver()
{
assert(_fd == INVALID_SOCKET);
-#ifndef ICEE_USE_SOCKET_TIMEOUT
+#ifdef ICEE_USE_SOCKET_TIMEOUT
#ifdef _WIN32
assert(_event == 0);
assert(_readEvent == 0);
@@ -372,6 +414,7 @@ IceInternal::Transceiver::~Transceiver()
#endif
}
+#ifdef ICEE_USE_SELECT_FOR_TIMEOUTS
void
IceInternal::Transceiver::doSelect(bool read, int timeout)
{
@@ -534,3 +577,4 @@ IceInternal::Transceiver::doSelect(bool read, int timeout)
#endif
}
}
+#endif