summaryrefslogtreecommitdiff
path: root/cppe/src
diff options
context:
space:
mode:
Diffstat (limited to 'cppe/src')
-rwxr-xr-xcppe/src/IceE/Connection.cpp19
-rw-r--r--cppe/src/IceE/Outgoing.cpp26
-rw-r--r--cppe/src/IceE/Proxy.cpp102
-rw-r--r--cppe/src/IceE/ProxyFactory.cpp77
-rw-r--r--cppe/src/IceE/Reference.cpp28
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;
}