diff options
author | Mark Spruiell <mes@zeroc.com> | 2005-04-12 20:50:00 +0000 |
---|---|---|
committer | Mark Spruiell <mes@zeroc.com> | 2005-04-12 20:50:00 +0000 |
commit | 3ac86ca67b43924dfddc0656f6d02b1d90f976b2 (patch) | |
tree | 37eebd9827ccc98fde9877a3e4f09f6f163daa5d /cpp/src | |
parent | fixing typo (diff) | |
download | ice-3ac86ca67b43924dfddc0656f6d02b1d90f976b2.tar.bz2 ice-3ac86ca67b43924dfddc0656f6d02b1d90f976b2.tar.xz ice-3ac86ca67b43924dfddc0656f6d02b1d90f976b2.zip |
fix for bug 218: Hang if oneways are not flushed
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Ice/Outgoing.cpp | 63 | ||||
-rw-r--r-- | cpp/src/Ice/ProxyFactory.cpp | 26 |
2 files changed, 61 insertions, 28 deletions
diff --git a/cpp/src/Ice/Outgoing.cpp b/cpp/src/Ice/Outgoing.cpp index 4c444b54ed5..bd98109ce16 100644 --- a/cpp/src/Ice/Outgoing.cpp +++ b/cpp/src/Ice/Outgoing.cpp @@ -62,40 +62,47 @@ IceInternal::Outgoing::Outgoing(ConnectionI* connection, Reference* ref, const s } } - _reference->getIdentity().__write(&_os); - - // - // For compatibility with the old FacetPath. - // - if(_reference->getFacet().empty()) + try { - _os.write(vector<string>()); - } - else - { - vector<string> facetPath; - facetPath.push_back(_reference->getFacet()); - _os.write(facetPath); - } + _reference->getIdentity().__write(&_os); - _os.write(operation); + // + // For compatibility with the old FacetPath. + // + if(_reference->getFacet().empty()) + { + _os.write(vector<string>()); + } + else + { + vector<string> facetPath; + facetPath.push_back(_reference->getFacet()); + _os.write(facetPath); + } + + _os.write(operation); - _os.write(static_cast<Byte>(mode)); + _os.write(static_cast<Byte>(mode)); - _os.writeSize(Int(context.size())); - Context::const_iterator p; - for(p = context.begin(); p != context.end(); ++p) + _os.writeSize(Int(context.size())); + Context::const_iterator p; + for(p = context.begin(); p != context.end(); ++p) + { + _os.write(p->first); + _os.write(p->second); + } + + // + // Input and output parameters are always sent in an + // encapsulation, which makes it possible to forward requests as + // blobs. + // + _os.startWriteEncaps(); + } + catch(const LocalException& ex) { - _os.write(p->first); - _os.write(p->second); + abort(ex); } - - // - // Input and output parameters are always sent in an - // encapsulation, which makes it possible to forward requests as - // blobs. - // - _os.startWriteEncaps(); } bool diff --git a/cpp/src/Ice/ProxyFactory.cpp b/cpp/src/Ice/ProxyFactory.cpp index 31f08404e25..0666f4b2777 100644 --- a/cpp/src/Ice/ProxyFactory.cpp +++ b/cpp/src/Ice/ProxyFactory.cpp @@ -109,6 +109,32 @@ IceInternal::ProxyFactory::checkRetryAfterException(const LocalException& ex, co ex.ice_throw(); } + // + // 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. + // + // 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. + // + // 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)) + { + ex.ice_throw(); + } + ++cnt; TraceLevelsPtr traceLevels = _instance->traceLevels(); |