diff options
Diffstat (limited to 'cppe/src')
-rwxr-xr-x | cppe/src/IceE/Connection.cpp | 19 | ||||
-rw-r--r-- | cppe/src/IceE/Outgoing.cpp | 26 | ||||
-rw-r--r-- | cppe/src/IceE/Proxy.cpp | 102 | ||||
-rw-r--r-- | cppe/src/IceE/ProxyFactory.cpp | 77 | ||||
-rw-r--r-- | cppe/src/IceE/Reference.cpp | 28 |
5 files changed, 147 insertions, 105 deletions
diff --git a/cppe/src/IceE/Connection.cpp b/cppe/src/IceE/Connection.cpp index 9c036b1b9a5..12ae0772a23 100755 --- a/cppe/src/IceE/Connection.cpp +++ b/cppe/src/IceE/Connection.cpp @@ -198,6 +198,18 @@ Ice::Connection::isFinished() const return true; } +void +Ice::Connection::throwException() const +{ + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this); + + if(_exception.get()) + { + assert(_state >= StateClosing); + _exception->ice_throw(); + } +} + #ifndef ICEE_PURE_CLIENT void @@ -303,7 +315,12 @@ Ice::Connection::sendRequest(BasicStream* os, Outgoing* out) if(!_transceiver) { assert(_exception.get()); - _exception->ice_throw(); + // + // If the connection is closed before we even have a chance + // to send our request, we always try to send the request + // again. + // + throw LocalExceptionWrapper(*_exception.get(), true); } Int requestId; diff --git a/cppe/src/IceE/Outgoing.cpp b/cppe/src/IceE/Outgoing.cpp index ad684ded0f0..7219fa58ae1 100644 --- a/cppe/src/IceE/Outgoing.cpp +++ b/cppe/src/IceE/Outgoing.cpp @@ -19,23 +19,31 @@ using namespace std; using namespace Ice; using namespace IceInternal; -IceInternal::NonRepeatable::NonRepeatable(const NonRepeatable& ex) +IceInternal::LocalExceptionWrapper::LocalExceptionWrapper(const LocalException& ex, bool r) : + _retry(r) { - _ex.reset(dynamic_cast<LocalException*>(ex.get()->ice_clone())); + _ex.reset(dynamic_cast<LocalException*>(ex.ice_clone())); } -IceInternal::NonRepeatable::NonRepeatable(const ::Ice::LocalException& ex) +IceInternal::LocalExceptionWrapper::LocalExceptionWrapper(const LocalExceptionWrapper& ex) : + _retry(ex._retry) { - _ex.reset(dynamic_cast<LocalException*>(ex.ice_clone())); + _ex.reset(dynamic_cast<LocalException*>(ex.get()->ice_clone())); } -const ::Ice::LocalException* -IceInternal::NonRepeatable::get() const +const LocalException* +IceInternal::LocalExceptionWrapper::get() const { assert(_ex.get()); return _ex.get(); } +bool +IceInternal::LocalExceptionWrapper::retry() const +{ + return _retry; +} + IceInternal::Outgoing::Outgoing(Connection* connection, Reference* ref, const string& operation, OperationMode mode, const Context& context) : _connection(connection), @@ -148,11 +156,11 @@ IceInternal::Outgoing::invoke() } // - // Throw the exception wrapped in a NonRepeatable, to + // Throw the exception wrapped in a LocalExceptionWrapper, to // indicate that the request cannot be resent without // potentially violating the "at-most-once" principle. // - throw NonRepeatable(*_exception.get()); + throw LocalExceptionWrapper(*_exception.get(), false); } if(_state == StateUserException) @@ -221,7 +229,7 @@ IceInternal::Outgoing::abort(const LocalException& ex) // only the batch request that caused the problem will be // aborted, but all other requests in the batch as well. // - throw NonRepeatable(ex); + throw LocalExceptionWrapper(ex, false); } #endif diff --git a/cppe/src/IceE/Proxy.cpp b/cppe/src/IceE/Proxy.cpp index 841b88a8c6c..2b3586f83ff 100644 --- a/cppe/src/IceE/Proxy.cpp +++ b/cppe/src/IceE/Proxy.cpp @@ -189,17 +189,20 @@ IceProxy::Ice::Object::ice_isA(const string& __id, const Context& __context) { if(!__ok) { - __stream->throwException(); + try + { + __stream->throwException(); + } + catch(const ::Ice::UserException& __ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name()); + } } __stream->read(__ret); } - catch(const ::Ice::UserException&) - { - throw ::Ice::UnknownUserException(__FILE__, __LINE__); - } catch(const ::Ice::LocalException& __ex) { - throw ::IceInternal::NonRepeatable(__ex); + throw ::IceInternal::LocalExceptionWrapper(__ex, false); } #if defined(_MSC_VER) && defined(_M_ARM) // ARM bug. catch(...) @@ -209,9 +212,9 @@ IceProxy::Ice::Object::ice_isA(const string& __id, const Context& __context) #endif return __ret; } - catch(const NonRepeatable& __ex) + catch(const LocalExceptionWrapper& __ex) { - __handleException(*__ex.get(), __cnt); + __handleExceptionWrapperRelaxed(__ex, __cnt); } catch(const LocalException& __ex) { @@ -249,16 +252,19 @@ IceProxy::Ice::Object::ice_ping(const Context& __context) BasicStream* __is = __og.stream(); if(!__ok) { - __is->throwException(); + try + { + __is->throwException(); + } + catch(const ::Ice::UserException& __ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name()); + } } } - catch(const ::Ice::UserException&) - { - throw ::Ice::UnknownUserException(__FILE__, __LINE__); - } catch(const ::Ice::LocalException& __ex) { - throw ::IceInternal::NonRepeatable(__ex); + throw ::IceInternal::LocalExceptionWrapper(__ex, false); } #if defined(_MSC_VER) && defined(_M_ARM) // ARM bug. catch(...) @@ -268,9 +274,9 @@ IceProxy::Ice::Object::ice_ping(const Context& __context) #endif return; } - catch(const NonRepeatable& __ex) + catch(const LocalExceptionWrapper& __ex) { - __handleException(*__ex.get(), __cnt); + __handleExceptionWrapperRelaxed(__ex, __cnt); } catch(const LocalException& __ex) { @@ -310,17 +316,20 @@ IceProxy::Ice::Object::ice_ids(const Context& __context) BasicStream* __is = __og.stream(); if(!__ok) { - __is->throwException(); + try + { + __is->throwException(); + } + catch(const ::Ice::UserException& __ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name()); + } } __is->read(__ret); } - catch(const ::Ice::UserException&) - { - throw ::Ice::UnknownUserException(__FILE__, __LINE__); - } catch(const ::Ice::LocalException& __ex) { - throw ::IceInternal::NonRepeatable(__ex); + throw ::IceInternal::LocalExceptionWrapper(__ex, false); } #if defined(_MSC_VER) && defined(_M_ARM) // ARM bug. catch(...) @@ -330,9 +339,9 @@ IceProxy::Ice::Object::ice_ids(const Context& __context) #endif return __ret; } - catch(const NonRepeatable& __ex) + catch(const LocalExceptionWrapper& __ex) { - __handleException(*__ex.get(), __cnt); + __handleExceptionWrapperRelaxed(__ex, __cnt); } catch(const LocalException& __ex) { @@ -372,17 +381,20 @@ IceProxy::Ice::Object::ice_id(const Context& __context) BasicStream* __is = __og.stream(); if(!__ok) { - __is->throwException(); + try + { + __is->throwException(); + } + catch(const ::Ice::UserException& __ex) + { + throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name()); + } } __is->read(__ret); } - catch(const ::Ice::UserException&) - { - throw ::Ice::UnknownUserException(__FILE__, __LINE__); - } catch(const ::Ice::LocalException& __ex) { - throw ::IceInternal::NonRepeatable(__ex); + throw ::IceInternal::LocalExceptionWrapper(__ex, false); } #if defined(_MSC_VER) && defined(_M_ARM) // ARM bug. catch(...) @@ -392,9 +404,9 @@ IceProxy::Ice::Object::ice_id(const Context& __context) #endif return __ret; } - catch(const NonRepeatable& __ex) + catch(const LocalExceptionWrapper& __ex) { - __handleException(*__ex.get(), __cnt); + __handleExceptionWrapperRelaxed(__ex, __cnt); } catch(const LocalException& __ex) { @@ -679,17 +691,31 @@ IceProxy::Ice::Object::__handleException(const LocalException& ex, int& cnt) } void -IceProxy::Ice::Object::__rethrowException(const LocalException& ex) +IceProxy::Ice::Object::__handleExceptionWrapper(const LocalExceptionWrapper& ex) { - // - // Only _connection needs to be mutex protected here. - // { - ::IceUtil::Mutex::Lock sync(*this); + IceUtil::Mutex::Lock sync(*this); _connection = 0; } - ex.ice_throw(); + if(!ex.retry()) + { + ex.get()->ice_throw(); + } +} + +void +IceProxy::Ice::Object::__handleExceptionWrapperRelaxed(const LocalExceptionWrapper& ex, int& cnt) +{ + if(!ex.retry()) + { + __handleException(*ex.get(), cnt); + } + else + { + IceUtil::Mutex::Lock sync(*this); + _connection = 0; + } } void diff --git a/cppe/src/IceE/ProxyFactory.cpp b/cppe/src/IceE/ProxyFactory.cpp index a55c3b83233..260ae5e9e70 100644 --- a/cppe/src/IceE/ProxyFactory.cpp +++ b/cppe/src/IceE/ProxyFactory.cpp @@ -115,24 +115,25 @@ IceInternal::ProxyFactory::checkRetryAfterException(const LocalException& ex, co // // There is no point in retrying an operation that resulted in a - // MarshalException. This must have been raised locally (because if - // it happened in a server it would result in an UnknownLocalException - // instead), which means there was a problem in this process that will - // not change if we try again. + // MarshalException. This must have been raised locally (because + // if it happened in a server it would result in an + // UnknownLocalException instead), which means there was a problem + // in this process that will not change if we try again. // // The most likely cause for a MarshalException is exceeding the // maximum message size, which is represented by the the subclass - // MemoryLimitException. For example, a client can attempt to send a - // message that exceeds the maximum memory size, or accumulate enough - // batch requests without flushing that the maximum size is reached. + // MemoryLimitException. For example, a client can attempt to send + // a message that exceeds the maximum memory size, or accumulate + // enough batch requests without flushing that the maximum size is + // reached. // - // This latter case is especially problematic, because if we were to - // retry a batch request after a MarshalException, we would in fact - // silently discard the accumulated requests and allow new batch - // requests to accumulate. If the subsequent batched requests do not - // exceed the maximum message size, it appears to the client that all - // of the batched requests were accepted, when in reality only the - // last few are actually sent. + // This latter case is especially problematic, because if we were + // to retry a batch request after a MarshalException, we would in + // fact silently discard the accumulated requests and allow new + // batch requests to accumulate. If the subsequent batched + // requests do not exceed the maximum message size, it appears to + // the client that all of the batched requests were accepted, when + // in reality only the last few are actually sent. // if(dynamic_cast<const MarshalException*>(&ex)) { @@ -140,52 +141,40 @@ IceInternal::ProxyFactory::checkRetryAfterException(const LocalException& ex, co } ++cnt; + assert(cnt > 0); TraceLevelsPtr traceLevels = _instance->traceLevels(); LoggerPtr logger = _instance->logger(); - // - // Instance components may be null if the communicator has been - // destroyed. - // - if(traceLevels && logger) + if(cnt > static_cast<int>(_retryIntervals.size())) { - if(cnt > static_cast<int>(_retryIntervals.size())) - { - if(traceLevels->retry >= 1) - { - Trace out(logger, traceLevels->retryCat); - out << "cannot retry operation call because retry limit has been exceeded\n" << ex.toString(); - } - ex.ice_throw(); - } - if(traceLevels->retry >= 1) { Trace out(logger, traceLevels->retryCat); - out << "re-trying operation call"; - if(cnt > 0 && _retryIntervals[cnt - 1] > 0) - { - out << Ice::printfToString(" in %dms", _retryIntervals[cnt - 1]); - } - out << " because of exception\n" << ex.toString(); + out << "cannot retry operation call because retry limit has been exceeded\n" << ex.toString(); } + ex.ice_throw(); + } + + int interval = _retryIntervals[cnt - 1]; - if(cnt > 0) + if(traceLevels->retry >= 1) + { + Trace out(logger, traceLevels->retryCat); + out << "re-trying operation call"; + if(interval > 0) { - // - // Sleep before retrying. - // - IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(_retryIntervals[cnt - 1])); + out << Ice::printfToString(" in %dms", interval); } + out << " because of exception\n" << ex.toString(); } - else + + if(cnt > 0) { // - // Impossible to retry after the communicator has been - // destroyed. + // Sleep before retrying. // - ex.ice_throw(); + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(_retryIntervals[cnt - 1])); } } diff --git a/cppe/src/IceE/Reference.cpp b/cppe/src/IceE/Reference.cpp index 9214deb990e..cabb645ef43 100644 --- a/cppe/src/IceE/Reference.cpp +++ b/cppe/src/IceE/Reference.cpp @@ -387,9 +387,9 @@ void IceInternal::decRef(IceInternal::FixedReference* p) { p->__decRef(); } IceInternal::FixedReference::FixedReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, Mode md, - const vector<ConnectionPtr>& fixedConns) - : Reference(inst, com, ident, ctx, fs, md, false), - _fixedConnections(fixedConns) + const vector<ConnectionPtr>& fixedConns) : + Reference(inst, com, ident, ctx, fs, md, false), + _fixedConnections(fixedConns) { } @@ -493,6 +493,7 @@ IceInternal::FixedReference::getConnection() const ConnectionPtr connection = randomCons[0]; assert(connection); + connection->throwException(); // Throw in case our connection is already destroyed. return connection; } @@ -546,9 +547,9 @@ IceInternal::FixedReference::clone() const return new FixedReference(*this); } -IceInternal::FixedReference::FixedReference(const FixedReference& r) - : Reference(r), - _fixedConnections(r._fixedConnections) +IceInternal::FixedReference::FixedReference(const FixedReference& r) : + Reference(r), + _fixedConnections(r._fixedConnections) { } @@ -635,13 +636,13 @@ IceInternal::RoutableReference::operator<(const Reference& r) const IceInternal::RoutableReference::RoutableReference(const InstancePtr& inst, const CommunicatorPtr& com, const Identity& ident, const Context& ctx, const string& fs, - Mode md, bool sec, const RouterInfoPtr& rtrInfo) - : Reference(inst, com, ident, ctx, fs, md, sec), _routerInfo(rtrInfo) + Mode md, bool sec, const RouterInfoPtr& rtrInfo) : + Reference(inst, com, ident, ctx, fs, md, sec), _routerInfo(rtrInfo) { } -IceInternal::RoutableReference::RoutableReference(const RoutableReference& r) - : Reference(r), _routerInfo(r._routerInfo) +IceInternal::RoutableReference::RoutableReference(const RoutableReference& r) : + Reference(r), _routerInfo(r._routerInfo) { } #endif @@ -853,8 +854,8 @@ IceInternal::DirectReference::clone() const return new DirectReference(*this); } -IceInternal::DirectReference::DirectReference(const DirectReference& r) - : Parent(r), _endpoints(r._endpoints) +IceInternal::DirectReference::DirectReference(const DirectReference& r) : + Parent(r), _endpoints(r._endpoints) { } @@ -1063,7 +1064,8 @@ IceInternal::IndirectReference::hash() const #else Reference::hash(); // Initializes _hashValue. #endif - for(string::const_iterator p = _adapterId.begin(); p != _adapterId.end(); ++p) // Add hash of adapter ID to base hash. + // Add hash of adapter ID to base hash + for(string::const_iterator p = _adapterId.begin(); p != _adapterId.end(); ++p) { _hashValue = 5 * _hashValue + *p; } |