diff options
author | Benoit Foucher <benoit@zeroc.com> | 2006-02-20 10:31:57 +0000 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2006-02-20 10:31:57 +0000 |
commit | e1d3d16e0fb475d771fbc476a3f1e88c9bcdc10f (patch) | |
tree | 03017261521ec7c308e3e092b15a74edcd6ca8e2 /cppe/src/TcpTransport/Transceiver.cpp | |
parent | porting new proxy methods for connection mgmt (diff) | |
download | ice-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.cpp | 318 |
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 |