diff options
author | Benoit Foucher <benoit@zeroc.com> | 2016-08-25 11:28:20 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2016-08-25 11:28:20 +0200 |
commit | 4fa256d3d27adffcc6529136cad904f0fbd490b0 (patch) | |
tree | 7250a0b630cfc8400745be4bdf7dde6891943b8c /cpp | |
parent | removing JavaCompat.ice (diff) | |
download | ice-4fa256d3d27adffcc6529136cad904f0fbd490b0.tar.bz2 ice-4fa256d3d27adffcc6529136cad904f0fbd490b0.tar.xz ice-4fa256d3d27adffcc6529136cad904f0fbd490b0.zip |
C++ dispatching code fixes
- removed user exception check on the server side (ICE-6980)
- C++11 dipatch interceptor async callback (ICE-7263)
- Fixed slicing/objects test in various mapping (removed Forward.ice)
Diffstat (limited to 'cpp')
23 files changed, 698 insertions, 1099 deletions
diff --git a/cpp/include/Ice/DispatchInterceptor.h b/cpp/include/Ice/DispatchInterceptor.h index 63a0a5e96e2..648e21412ca 100644 --- a/cpp/include/Ice/DispatchInterceptor.h +++ b/cpp/include/Ice/DispatchInterceptor.h @@ -19,11 +19,9 @@ class ICE_API DispatchInterceptor : public virtual Object { public: - virtual DispatchStatus - dispatch(Request&) = 0; + virtual bool dispatch(Request&) = 0; - virtual DispatchStatus - __dispatch(IceInternal::Incoming&, const Current&); + virtual bool __dispatch(IceInternal::Incoming&, const Current&); }; ICE_DEFINE_PTR(DispatchInterceptorPtr, DispatchInterceptor); diff --git a/cpp/include/Ice/Incoming.h b/cpp/include/Ice/Incoming.h index 03193854195..f322d2de1ea 100644 --- a/cpp/include/Ice/Incoming.h +++ b/cpp/include/Ice/Incoming.h @@ -31,27 +31,27 @@ class ICE_API IncomingBase : private IceUtil::noncopyable { public: - void __adopt(IncomingBase&); + Ice::OutputStream* startWriteParams(); + void endWriteParams(); + void writeEmptyParams(); + void writeParamEncaps(const Ice::Byte*, Ice::Int, bool); - Ice::OutputStream* __startWriteParams(Ice::FormatType); - void __endWriteParams(bool); - void __writeEmptyParams(); - void __writeParamEncaps(const Ice::Byte*, Ice::Int, bool); - void __writeUserException(const Ice::UserException&, Ice::FormatType); + void response(bool); + void exception(const std::exception&, bool); + void exception(const std::string&, bool); protected: - IncomingBase(Instance*, ResponseHandler*, Ice::Connection*, const Ice::ObjectAdapterPtr&, bool, Ice::Byte, - Ice::Int); - IncomingBase(IncomingBase&); // Adopts the argument. It must not be used afterwards. + IncomingBase(Instance*, ResponseHandler*, Ice::Connection*, const Ice::ObjectAdapterPtr&, bool, Ice::Byte, Ice::Int); + IncomingBase(IncomingBase&); - void __warning(const Ice::Exception&) const; - void __warning(const std::string&) const; + void warning(const Ice::Exception&) const; + void warning(const std::string&) const; - bool __servantLocatorFinished(bool); + bool servantLocatorFinished(bool); - void __handleException(const std::exception&, bool); - void __handleException(bool); + void handleException(const std::exception&, bool); + void handleException(const std::string&, bool); Ice::Current _current; Ice::ObjectPtr _servant; @@ -64,7 +64,7 @@ protected: DispatchObserver _observer; bool _response; Ice::Byte _compress; - + Ice::FormatType _format; Ice::OutputStream _os; // @@ -73,7 +73,13 @@ protected: // ResponseHandler* _responseHandler; - std::deque<Ice::DispatchInterceptorAsyncCallbackPtr> _interceptorAsyncCallbackQueue; +#ifdef ICE_CPP11_MAPPING + using DispatchInterceptorCallbacks = std::deque<std::pair<std::function<bool()>, + std::function<bool(std::exception_ptr)>>>; +#else + typedef std::deque<Ice::DispatchInterceptorAsyncCallbackPtr> DispatchInterceptorCallbacks; +#endif + DispatchInterceptorCallbacks _interceptorCBs; }; class ICE_API Incoming : public IncomingBase @@ -87,20 +93,33 @@ public: return _current; } +#ifdef ICE_CPP11_MAPPING + void push(std::function<bool()>, std::function<bool(std::exception_ptr)>); +#else void push(const Ice::DispatchInterceptorAsyncCallbackPtr&); +#endif void pop(); + + void setAsync(const IncomingAsyncPtr& in) + { + assert(!_inAsync); + _inAsync = in; + } + void startOver(); - void killAsync(); - void setActive(IncomingAsyncPtr); - bool isRetriable() + void setFormat(Ice::FormatType format) { - return _inParamPos != 0; + _format = format; } void invoke(const ServantManagerPtr&, Ice::InputStream*); // Inlined for speed optimization. + void skipReadParams() + { + _current.encoding = _is->skipEncapsulation(); + } Ice::InputStream* startReadParams() { // @@ -125,10 +144,12 @@ public: private: - Ice::InputStream* _is; + friend class IncomingAsync; - IncomingAsyncPtr _cb; + Ice::InputStream* _is; Ice::Byte* _inParamPos; + + IncomingAsyncPtr _inAsync; }; } diff --git a/cpp/include/Ice/IncomingAsync.h b/cpp/include/Ice/IncomingAsync.h index edffd56dda6..474f6032761 100644 --- a/cpp/include/Ice/IncomingAsync.h +++ b/cpp/include/Ice/IncomingAsync.h @@ -17,7 +17,7 @@ namespace Ice { -class ICE_API AMDCallback : public virtual Ice::LocalObject +class ICE_API AMDCallback : public Ice::LocalObject { public: @@ -45,52 +45,55 @@ class ICE_API IncomingAsync : public IncomingBase, public virtual Ice::AMDCallback #endif { -#ifdef ICE_CPP11_MAPPING public: - // - // The constructor is public but it shouldn't be used directly, use create() instead. - // IncomingAsync(Incoming&); - static IncomingAsyncPtr create(Incoming&); // Adopts the argument. It must not be used afterwards. - -#else +#ifdef ICE_CPP11_MAPPING -protected: + static std::shared_ptr<IncomingAsync> create(Incoming&); - IncomingAsync(Incoming&); -#endif + std::function<void()> response() + { + auto self = shared_from_this(); + return [self]() + { + self->writeEmptyParams(); + self->completed(); + }; + } -public: + std::function<void(std::exception_ptr)> exception() + { + auto self = shared_from_this(); + return [self](std::exception_ptr ex) { self->completed(ex); }; + } - void __deactivate(Incoming&); +#else virtual void ice_exception(const ::std::exception&); virtual void ice_exception(); - void __response(); - void __exception(const std::exception&); - void __exception(); +#endif + + void kill(Incoming&); - bool __validateResponse(bool); + void completed(); + +#ifdef ICE_CPP11_MAPPING + void completed(std::exception_ptr); +#endif private: - // - // We need a separate InstancePtr, because _is and _os only hold a - // Instance* for optimization. - // - const InstancePtr _instanceCopy; + void checkResponseSent(); + bool _responseSent; // // We need a separate ConnectionIPtr, because IncomingBase only // holds a ConnectionI* for optimization. // const ResponseHandlerPtr _responseHandlerCopy; - - const bool _retriable; - bool _active; }; } diff --git a/cpp/include/Ice/IncomingAsyncF.h b/cpp/include/Ice/IncomingAsyncF.h index 5161faa8a15..9b28e60d921 100644 --- a/cpp/include/Ice/IncomingAsyncF.h +++ b/cpp/include/Ice/IncomingAsyncF.h @@ -14,24 +14,20 @@ #include <Ice/Handle.h> -#ifdef ICE_CPP11_MAPPING namespace IceInternal { class IncomingAsync; +#ifdef ICE_CPP11_MAPPING using IncomingAsyncPtr = ::std::shared_ptr<IncomingAsync>; - -} #else -namespace IceInternal -{ - -class IncomingAsync; ICE_API IceUtil::Shared* upCast(IncomingAsync*); typedef IceInternal::Handle<IncomingAsync> IncomingAsyncPtr; +#endif } +#ifndef ICE_CPP11_MAPPING namespace Ice { diff --git a/cpp/include/Ice/Object.h b/cpp/include/Ice/Object.h index b39b9240cec..6e472bd5fee 100644 --- a/cpp/include/Ice/Object.h +++ b/cpp/include/Ice/Object.h @@ -40,28 +40,19 @@ namespace Ice ICE_API extern const Current noExplicitCurrent; -enum DispatchStatus -{ - DispatchOK, - DispatchUserException, - DispatchAsync -}; - - -class ICE_API DispatchInterceptorAsyncCallback #ifndef ICE_CPP11_MAPPING - : public virtual IceUtil::Shared -#endif +class ICE_API DispatchInterceptorAsyncCallback : public virtual IceUtil::Shared { public: virtual ~DispatchInterceptorAsyncCallback(); - virtual bool response(bool) = 0; + virtual bool response() = 0; virtual bool exception(const std::exception&) = 0; virtual bool exception() = 0; }; ICE_DEFINE_PTR(DispatchInterceptorAsyncCallbackPtr, DispatchInterceptorAsyncCallback); +#endif class ICE_API Request { @@ -79,23 +70,29 @@ public: virtual ~Object() = default; virtual bool ice_isA(std::string, const Current& = Ice::noExplicitCurrent) const; - DispatchStatus ___ice_isA(IceInternal::Incoming&, const Current&); + bool ___ice_isA(IceInternal::Incoming&, const Current&); virtual void ice_ping(const Current& = Ice::noExplicitCurrent) const; - DispatchStatus ___ice_ping(IceInternal::Incoming&, const Current&); + bool ___ice_ping(IceInternal::Incoming&, const Current&); virtual std::vector< std::string> ice_ids(const Current& = Ice::noExplicitCurrent) const; - DispatchStatus ___ice_ids(IceInternal::Incoming&, const Current&); + bool ___ice_ids(IceInternal::Incoming&, const Current&); virtual std::string ice_id(const Current& = Ice::noExplicitCurrent) const; - DispatchStatus ___ice_id(IceInternal::Incoming&, const Current&); + bool ___ice_id(IceInternal::Incoming&, const Current&); static const std::string& ice_staticId(); static std::string __all[]; - virtual DispatchStatus ice_dispatch(Ice::Request&, const DispatchInterceptorAsyncCallbackPtr& = 0); - virtual DispatchStatus __dispatch(IceInternal::Incoming&, const Current&); +#ifndef ICE_CPP11_MAPPING + virtual bool ice_dispatch(Ice::Request&, const DispatchInterceptorAsyncCallbackPtr& = 0); +#else + virtual bool ice_dispatch(Ice::Request&, + std::function<bool()> = nullptr, + std::function<bool(std::exception_ptr)> = nullptr); +#endif + virtual bool __dispatch(IceInternal::Incoming&, const Current&); struct Ice_invokeResult { @@ -116,16 +113,16 @@ public: virtual bool operator<(const Object&) const; virtual bool ice_isA(const std::string&, const Current& = Ice::noExplicitCurrent) const; - DispatchStatus ___ice_isA(IceInternal::Incoming&, const Current&); + bool ___ice_isA(IceInternal::Incoming&, const Current&); virtual void ice_ping(const Current& = Ice::noExplicitCurrent) const; - DispatchStatus ___ice_ping(IceInternal::Incoming&, const Current&); + bool ___ice_ping(IceInternal::Incoming&, const Current&); virtual std::vector< std::string> ice_ids(const Current& = Ice::noExplicitCurrent) const; - DispatchStatus ___ice_ids(IceInternal::Incoming&, const Current&); + bool ___ice_ids(IceInternal::Incoming&, const Current&); virtual const std::string& ice_id(const Current& = Ice::noExplicitCurrent) const; - DispatchStatus ___ice_id(IceInternal::Incoming&, const Current&); + bool ___ice_id(IceInternal::Incoming&, const Current&); virtual Int ice_operationAttributes(const std::string&) const; @@ -144,8 +141,8 @@ public: static std::string __all[]; - virtual DispatchStatus ice_dispatch(Ice::Request&, const DispatchInterceptorAsyncCallbackPtr& = 0); - virtual DispatchStatus __dispatch(IceInternal::Incoming&, const Current&); + virtual bool ice_dispatch(Ice::Request&, const DispatchInterceptorAsyncCallbackPtr& = 0); + virtual bool __dispatch(IceInternal::Incoming&, const Current&); protected: @@ -170,7 +167,7 @@ public: // virtual bool ice_invoke(const std::vector<Byte>&, std::vector<Byte>&, const Current&) = 0; - virtual DispatchStatus __dispatch(IceInternal::Incoming&, const Current&); + virtual bool __dispatch(IceInternal::Incoming&, const Current&); }; class ICE_API BlobjectArray : public virtual Object @@ -182,7 +179,7 @@ public: // virtual bool ice_invoke(const std::pair<const Byte*, const Byte*>&, std::vector<Byte>&, const Current&) = 0; - virtual DispatchStatus __dispatch(IceInternal::Incoming&, const Current&); + virtual bool __dispatch(IceInternal::Incoming&, const Current&); }; class ICE_API BlobjectAsync : public virtual Object @@ -197,7 +194,7 @@ public: #else virtual void ice_invoke_async(const AMD_Object_ice_invokePtr&, const std::vector<Byte>&, const Current&) = 0; #endif - virtual DispatchStatus __dispatch(IceInternal::Incoming&, const Current&); + virtual bool __dispatch(IceInternal::Incoming&, const Current&); }; class ICE_API BlobjectArrayAsync : public virtual Object @@ -213,7 +210,7 @@ public: virtual void ice_invoke_async(const AMD_Object_ice_invokePtr&, const std::pair<const Byte*, const Byte*>&, const Current&) = 0; #endif - virtual DispatchStatus __dispatch(IceInternal::Incoming&, const Current&); + virtual bool __dispatch(IceInternal::Incoming&, const Current&); }; } diff --git a/cpp/src/Ice/DispatchInterceptor.cpp b/cpp/src/Ice/DispatchInterceptor.cpp index 4b320ff9a53..b9d87096848 100644 --- a/cpp/src/Ice/DispatchInterceptor.cpp +++ b/cpp/src/Ice/DispatchInterceptor.cpp @@ -14,36 +14,16 @@ using namespace Ice; using namespace IceInternal; -DispatchStatus +bool Ice::DispatchInterceptor::__dispatch(IceInternal::Incoming& in, const Current& /*current*/) { try { IncomingRequest request(in); - DispatchStatus status = dispatch(request); - if(status != DispatchAsync) - { - // - // Make sure 'in' owns the connection etc. - // - in.killAsync(); - } - return status; + return dispatch(request); } catch(const ResponseSentException&) { - return DispatchAsync; - } - catch(...) - { - try - { - in.killAsync(); - } - catch(const ResponseSentException&) - { - return DispatchAsync; - } - throw; + return false; } } diff --git a/cpp/src/Ice/Incoming.cpp b/cpp/src/Ice/Incoming.cpp index d100160b573..1f6da2bdd92 100644 --- a/cpp/src/Ice/Incoming.cpp +++ b/cpp/src/Ice/Incoming.cpp @@ -42,6 +42,7 @@ IceInternal::IncomingBase::IncomingBase(Instance* instance, ResponseHandler* res bool response, Byte compress, Int requestId) : _response(response), _compress(compress), + _format(Ice::DefaultFormat), _os(instance, Ice::currentProtocolEncoding), _responseHandler(responseHandler) { @@ -55,92 +56,62 @@ IceInternal::IncomingBase::IncomingBase(Instance* instance, ResponseHandler* res _current.requestId = requestId; } -IceInternal::IncomingBase::IncomingBase(IncomingBase& in) : - _current(in._current), // copy - _os(in._os.instance(), Ice::currentProtocolEncoding), - _interceptorAsyncCallbackQueue(in._interceptorAsyncCallbackQueue) // copy -{ - __adopt(in); // adopt everything else -} - -void -IceInternal::IncomingBase::__adopt(IncomingBase& other) +IceInternal::IncomingBase::IncomingBase(IncomingBase& other) : + _current(other._current), + _servant(other._servant), + _locator(other._locator), + _cookie(other._cookie), + _response(other._response), + _compress(other._compress), + _format(other._format), + _os(other._os.instance(), Ice::currentProtocolEncoding), + _responseHandler(other._responseHandler), + _interceptorCBs(other._interceptorCBs) { _observer.adopt(other._observer); - - _servant = other._servant; - other._servant = 0; - - _locator = other._locator; - other._locator = 0; - - _cookie = other._cookie; - other._cookie = 0; - - _response = other._response; - other._response = false; - - _compress = other._compress; - other._compress = 0; - - _os.swap(other._os); - - _responseHandler = other._responseHandler; - other._responseHandler = 0; } OutputStream* -IncomingBase::__startWriteParams(FormatType format) +IncomingBase::startWriteParams() { if(!_response) { throw MarshalException(__FILE__, __LINE__, "can't marshal out parameters for oneway dispatch"); } - assert(_os.b.size() == headerSize + 4); // Reply status position. assert(_current.encoding >= Ice::Encoding_1_0); // Encoding for reply is known. - _os.write(static_cast<Ice::Byte>(0)); - _os.startEncapsulation(_current.encoding, format); - // - // We still return the stream even if no response is expected. The - // servant code might still write some out parameters if for - // example a method with out parameters somehow and erroneously - // invoked as oneway (or if the invocation is invoked on a - // blobject and the blobject erroneously writes a response). - // + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + _os.write(replyOK); + _os.startEncapsulation(_current.encoding, _format); return &_os; } void -IncomingBase::__endWriteParams(bool ok) +IncomingBase::endWriteParams() { - if(!ok) - { - _observer.userException(); - } - if(_response) { - *(_os.b.begin() + headerSize + 4) = ok ? replyOK : replyUserException; // Reply status position. _os.endEncapsulation(); } } void -IncomingBase::__writeEmptyParams() +IncomingBase::writeEmptyParams() { if(_response) { - assert(_os.b.size() == headerSize + 4); // Reply status position. assert(_current.encoding >= Ice::Encoding_1_0); // Encoding for reply is known. + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); _os.write(replyOK); _os.writeEmptyEncapsulation(_current.encoding); } } void -IncomingBase::__writeParamEncaps(const Byte* v, Ice::Int sz, bool ok) +IncomingBase::writeParamEncaps(const Byte* v, Ice::Int sz, bool ok) { if(!ok) { @@ -149,8 +120,9 @@ IncomingBase::__writeParamEncaps(const Byte* v, Ice::Int sz, bool ok) if(_response) { - assert(_os.b.size() == headerSize + 4); // Reply status position. assert(_current.encoding >= Ice::Encoding_1_0); // Encoding for reply is known. + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); _os.write(ok ? replyOK : replyUserException); if(sz == 0) { @@ -164,15 +136,71 @@ IncomingBase::__writeParamEncaps(const Byte* v, Ice::Int sz, bool ok) } void -IncomingBase::__writeUserException(const Ice::UserException& ex, Ice::FormatType format) +IceInternal::IncomingBase::response(bool amd) +{ + try + { + if(_locator && !servantLocatorFinished(amd)) + { + return; + } + + assert(_responseHandler); + if(_response) + { + _observer.reply(static_cast<Int>(_os.b.size() - headerSize - 4)); + _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); + } + else + { + _responseHandler->sendNoResponse(); + } + } + catch(const LocalException& ex) + { + _responseHandler->invokeException(_current.requestId, ex, 1, amd); // Fatal invocation exception + } + + _observer.detach(); + _responseHandler = 0; +} + +void +IceInternal::IncomingBase::exception(const std::exception& exc, bool amd) { - ::Ice::OutputStream* __os = __startWriteParams(format); - __os->write(ex); - __endWriteParams(false); + try + { + if(_locator && !servantLocatorFinished(amd)) + { + return; + } + handleException(exc, amd); + } + catch(const LocalException& ex) + { + _responseHandler->invokeException(_current.requestId, ex, 1, amd); // Fatal invocation exception + } } void -IceInternal::IncomingBase::__warning(const Exception& ex) const +IceInternal::IncomingBase::exception(const string& msg, bool amd) +{ + try + { + if(_locator && !servantLocatorFinished(amd)) + { + return; + } + handleException(msg, amd); + } + catch(const LocalException& ex) + { + _responseHandler->invokeException(_current.requestId, ex, 1, amd); // Fatal invocation exception + } +} + +void +IceInternal::IncomingBase::warning(const Exception& ex) const { Warning out(_os.instance()->initializationData().logger); @@ -196,7 +224,7 @@ IceInternal::IncomingBase::__warning(const Exception& ex) const } void -IceInternal::IncomingBase::__warning(const string& msg) const +IceInternal::IncomingBase::warning(const string& msg) const { Warning out(_os.instance()->initializationData().logger); @@ -220,7 +248,7 @@ IceInternal::IncomingBase::__warning(const string& msg) const } bool -IceInternal::IncomingBase::__servantLocatorFinished(bool amd) +IceInternal::IncomingBase::servantLocatorFinished(bool amd) { assert(_locator && _servant); try @@ -228,49 +256,27 @@ IceInternal::IncomingBase::__servantLocatorFinished(bool amd) _locator->finished(_current, _servant, _cookie); return true; } - catch(const UserException& ex) - { - assert(_responseHandler); - - _observer.userException(); - - // - // The operation may have already marshaled a reply; we must overwrite that reply. - // - if(_response) - { - _os.b.resize(headerSize + 4); // Reply status position. - _os.write(replyUserException); - _os.startEncapsulation(_current.encoding, DefaultFormat); - _os.write(ex); - _os.endEncapsulation(); - _observer.reply(static_cast<Int>(_os.b.size() - headerSize - 4)); - _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); - } - else - { - _responseHandler->sendNoResponse(); - } - - _observer.detach(); - _responseHandler = 0; - } catch(const std::exception& ex) { - __handleException(ex, amd); + handleException(ex, amd); } catch(...) { - __handleException(amd); + handleException("unknown c++ exception", amd); } return false; } void -IceInternal::IncomingBase::__handleException(const std::exception& exc, bool amd) +IceInternal::IncomingBase::handleException(const std::exception& exc, bool amd) { assert(_responseHandler); + // Reset the stream, it's possible the marshalling of the response failed and left + // the stream in an unknown state. + _os.clear(); + _os.b.clear(); + if(const SystemException* ex = dynamic_cast<const SystemException*>(&exc)) { if(_responseHandler->systemException(_current.requestId, *ex, amd)) @@ -301,7 +307,7 @@ IceInternal::IncomingBase::__handleException(const std::exception& exc, bool amd if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 1) { - __warning(*rfe); + warning(*rfe); } if(_observer) @@ -311,7 +317,8 @@ IceInternal::IncomingBase::__handleException(const std::exception& exc, bool amd if(_response) { - _os.b.resize(headerSize + 4); // Reply status position. + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); if(dynamic_cast<ObjectNotExistException*>(rfe)) { _os.write(replyObjectNotExist); @@ -353,11 +360,34 @@ IceInternal::IncomingBase::__handleException(const std::exception& exc, bool amd _responseHandler->sendNoResponse(); } } + else if(const UserException* ex = dynamic_cast<const UserException*>(&exc)) + { + _observer.userException(); + + // + // The operation may have already marshaled a reply; we must overwrite that reply. + // + if(_response) + { + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); + _os.write(replyUserException); + _os.startEncapsulation(_current.encoding, _format); + _os.write(*ex); + _os.endEncapsulation(); + _observer.reply(static_cast<Int>(_os.b.size() - headerSize - 4)); + _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); + } + else + { + _responseHandler->sendNoResponse(); + } + } else if(const Exception* ex = dynamic_cast<const Exception*>(&exc)) { if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) { - __warning(*ex); + warning(*ex); } if(_observer) @@ -367,7 +397,8 @@ IceInternal::IncomingBase::__handleException(const std::exception& exc, bool amd if(_response) { - _os.b.resize(headerSize + 4); // Reply status position. + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); if(const UnknownLocalException* ule = dynamic_cast<const UnknownLocalException*>(&exc)) { _os.write(replyUnknownLocalException); @@ -429,7 +460,7 @@ IceInternal::IncomingBase::__handleException(const std::exception& exc, bool amd { if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) { - __warning(string("std::exception: ") + exc.what()); + warning(string("std::exception: ") + exc.what()); } if(_observer) @@ -439,7 +470,8 @@ IceInternal::IncomingBase::__handleException(const std::exception& exc, bool amd if(_response) { - _os.b.resize(headerSize + 4); // Reply status position. + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); _os.write(replyUnknownException); ostringstream str; str << "std::exception: " << exc.what(); @@ -459,15 +491,20 @@ IceInternal::IncomingBase::__handleException(const std::exception& exc, bool amd } void -IceInternal::IncomingBase::__handleException(bool amd) +IceInternal::IncomingBase::handleException(const string& msg, bool amd) { if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) { - __warning("unknown c++ exception"); + warning(msg); } assert(_responseHandler); + // Reset the stream, it's possible the marshalling of the response failed and left + // the stream in an unknown state. + _os.clear(); + _os.b.clear(); + if(_observer) { _observer.failed("unknown"); @@ -475,9 +512,10 @@ IceInternal::IncomingBase::__handleException(bool amd) if(_response) { - _os.b.resize(headerSize + 4); // Reply status position. + _os.writeBlob(replyHdr, sizeof(replyHdr)); + _os.write(_current.requestId); _os.write(replyUnknownException); - string reason = "unknown c++ exception"; + string reason = msg; _os.write(reason, false); _observer.reply(static_cast<Int>(_os.b.size() - headerSize - 4)); _responseHandler->sendResponse(_current.requestId, &_os, _compress, amd); @@ -497,31 +535,26 @@ IceInternal::Incoming::Incoming(Instance* instance, ResponseHandler* responseHan IncomingBase(instance, responseHandler, connection, adapter, response, compress, requestId), _inParamPos(0) { - // - // Prepare the response if necessary. - // - if(response) - { - _os.writeBlob(replyHdr, sizeof(replyHdr)); - - // - // Add the request ID. - // - _os.write(requestId); - } } - +#ifdef ICE_CPP11_MAPPING +void +IceInternal::Incoming::push(function<bool()> response, function<bool(exception_ptr)> exception) +{ + _interceptorCBs.push_front(make_pair(response, exception)); +} +#else void IceInternal::Incoming::push(const Ice::DispatchInterceptorAsyncCallbackPtr& cb) { - _interceptorAsyncCallbackQueue.push_front(cb); + _interceptorCBs.push_front(cb); } +#endif void IceInternal::Incoming::pop() { - _interceptorAsyncCallbackQueue.pop_front(); + _interceptorCBs.pop_front(); } void @@ -536,47 +569,20 @@ IceInternal::Incoming::startOver() } else { - killAsync(); + // Reset input stream's position and clear response + if(_inAsync) + { + _inAsync->kill(*this); + _inAsync = 0; + } + _os.clear(); + _os.b.clear(); - // - // Let's rewind _is and clean-up _os - // _is->i = _inParamPos; - _os.b.resize(headerSize + 4); // Reply status position. } } void -IceInternal::Incoming::killAsync() -{ - // - // Always runs in the dispatch thread - // - if(_cb != 0) - { - // - // May raise ResponseSentException - // - _cb->__deactivate(*this); - _cb = 0; - } -} - -void -IceInternal::Incoming::setActive(IncomingAsyncPtr cb) -{ - assert(_cb == 0); - // - // acquires a ref-count - // -#ifdef ICE_CPP11_MAPPING - _cb = move(cb); -#else - _cb = cb; -#endif -} - -void IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager, InputStream* stream) { _is = stream; @@ -655,72 +661,26 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager, InputStre { _servant = _locator->locate(_current, _cookie); } - catch(const UserException& ex) - { - Ice::EncodingVersion encoding = _is->skipEncapsulation(); // Required for batch requests. - - _observer.userException(); - - if(_response) - { - _os.write(replyUserException); - _os.startEncapsulation(encoding, DefaultFormat); - _os.write(ex); - _os.endEncapsulation(); - _observer.reply(static_cast<Int>(_os.b.size() - headerSize - 4)); - _responseHandler->sendResponse(_current.requestId, &_os, _compress, false); - } - else - { - _responseHandler->sendNoResponse(); - } - - _observer.detach(); - _responseHandler = 0; - return; - } catch(const std::exception& ex) { - _is->skipEncapsulation(); // Required for batch requests. - __handleException(ex, false); + skipReadParams(); // Required for batch requests. + handleException(ex, false); return; } catch(...) { - _is->skipEncapsulation(); // Required for batch requests. - __handleException(false); + skipReadParams(); // Required for batch requests. + handleException("unknown c++ exception", false); return; } } } } - try + if(!_servant) { - if(_servant) + try { - // - // DispatchAsync is a "pseudo dispatch status", used internally only - // to indicate async dispatch. - // - if(_servant->__dispatch(*this, _current) == DispatchAsync) - { - return; - } - - if(_locator && !__servantLocatorFinished(false)) - { - return; - } - } - else - { - // - // Skip the input parameters, this is required for reading - // the next batch request if dispatching batch requests. - // - _is->skipEncapsulation(); - if(servantManager && servantManager->hasServant(_current.id)) { throw FacetNotExistException(__FILE__, __LINE__, _current.id, _current.facet, _current.operation); @@ -730,44 +690,88 @@ IceInternal::Incoming::invoke(const ServantManagerPtr& servantManager, InputStre throw ObjectNotExistException(__FILE__, __LINE__, _current.id, _current.facet, _current.operation); } } - } - catch(const std::exception& ex) - { - if(_servant && _locator && !__servantLocatorFinished(false)) + catch(const Ice::LocalException& ex) { + skipReadParams(); // Required for batch requests + handleException(ex, false); return; } - __handleException(ex, false); - return; } - catch(...) + + try { - if(_servant && _locator && !__servantLocatorFinished(false)) + // + // Dispatch in the incoming call + // + _servant->__dispatch(*this, _current); + + // + // If the request was not dispatched asynchronously, send the response. + // + if(!_inAsync) { - return; + response(false); } - __handleException(false); - return; } - - // - // Don't put the code below into the try block above. Exceptions - // in the code below are considered fatal, and must propagate to - // the caller of this operation. - // - - if(_response) + catch(const std::exception& ex) { - _observer.reply(static_cast<Int>(_os.b.size() - headerSize - 4)); - _responseHandler->sendResponse(_current.requestId, &_os, _compress, false); + if(_inAsync) + { + try + { +#ifdef ICE_CPP11_MAPPING + _inAsync->completed(current_exception()); +#else + _inAsync->ice_exception(ex); +#endif + } + catch(const Ice::ResponseSentException&) + { + const Ice::PropertiesPtr properties = _os.instance()->initializationData().properties; + if(properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) + { + if(const IceUtil::Exception* exc = dynamic_cast<const IceUtil::Exception*>(&ex)) + { + warning(*exc); + } + else + { + warning(string("std::exception: ") + ex.what()); + } + } + } + } + else + { + exception(ex, false); + } } - else + catch(...) { - _responseHandler->sendNoResponse(); + if(_inAsync) + { + try + { +#ifdef ICE_CPP11_MAPPING + _inAsync->completed(current_exception()); +#else + _inAsync->ice_exception(); +#endif + } + catch(const Ice::ResponseSentException&) + { + const Ice::PropertiesPtr properties = _os.instance()->initializationData().properties; + if(properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) + { + warning("unknown c++ exception"); + } + } + } + else + { + exception("unknown c++ exception", false); + } } - - _observer.detach(); - _responseHandler = 0; } const Current& diff --git a/cpp/src/Ice/IncomingAsync.cpp b/cpp/src/Ice/IncomingAsync.cpp index 7c9f248ed89..d9bcbc5b797 100644 --- a/cpp/src/Ice/IncomingAsync.cpp +++ b/cpp/src/Ice/IncomingAsync.cpp @@ -65,305 +65,169 @@ Init init; IceInternal::IncomingAsync::IncomingAsync(Incoming& in) : IncomingBase(in), - _instanceCopy(_os.instance()), - _responseHandlerCopy(ICE_GET_SHARED_FROM_THIS(_responseHandler)), // Acquire reference on response handler - _retriable(in.isRetriable()), - _active(true) + _responseSent(false), + _responseHandlerCopy(ICE_GET_SHARED_FROM_THIS(_responseHandler)) { #ifndef ICE_CPP11_MAPPING - if(_retriable) - { - in.setActive(this); - } + in.setAsync(this); #endif } #ifdef ICE_CPP11_MAPPING -IncomingAsyncPtr +shared_ptr<IncomingAsync> IceInternal::IncomingAsync::create(Incoming& in) { - IncomingAsyncPtr self = make_shared<IncomingAsync>(in); - if(in.isRetriable()) - { - in.setActive(self->shared_from_this()); - } - return self; + auto async = make_shared<IncomingAsync>(in); + in.setAsync(async); + return async; } #endif +#ifndef ICE_CPP11_MAPPING void -IceInternal::IncomingAsync::__deactivate(Incoming& in) +IceInternal::IncomingAsync::ice_exception(const ::std::exception& exc) { - assert(_retriable); + for(DispatchInterceptorCallbacks::iterator p = _interceptorCBs.begin(); p != _interceptorCBs.end(); ++p) { - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex); - if(!_active) + try + { + if(!(*p)->exception(exc)) + { + return; + } + } + catch(...) { - // - // Since _deactivate can only be called on an active object, - // this means the response has already been sent (see __validateXXX below) - // - throw ResponseSentException(__FILE__, __LINE__); } - _active = false; } - in.__adopt(*this); + checkResponseSent(); + IncomingBase::exception(exc, true); // User thread } void -IceInternal::IncomingAsync::ice_exception(const ::std::exception& ex) +IceInternal::IncomingAsync::ice_exception() { - // - // Only call __exception if this incoming is not retriable or if - // all the interceptors return true and no response has been sent - // yet. - // - - if(_retriable) + for(DispatchInterceptorCallbacks::iterator p = _interceptorCBs.begin(); p != _interceptorCBs.end(); ++p) { try { - for(deque<Ice::DispatchInterceptorAsyncCallbackPtr>::iterator p = _interceptorAsyncCallbackQueue.begin(); - p != _interceptorAsyncCallbackQueue.end(); ++p) + if(!(*p)->exception()) { - if((*p)->exception(ex) == false) - { - return; - } + return; } } catch(...) { - return; } - - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex); - if(!_active) - { - return; - } - _active = false; } - if(_responseHandler) - { - __exception(ex); - } - else - { - // - // Response has already been sent. - // - if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) - { - __warning(ex.what()); - } - } + checkResponseSent(); + IncomingBase::exception("unknown c++ exception", true); // User thread } +#endif + void -IceInternal::IncomingAsync::ice_exception() +IceInternal::IncomingAsync::kill(Incoming& in) { - // - // Only call __exception if this incoming is not retriable or if - // all the interceptors return true and no response has been sent - // yet. - // + checkResponseSent(); + in._observer.adopt(_observer); // Give back the observer to incoming. +} - if(_retriable) +void +IceInternal::IncomingAsync::completed() +{ + for(DispatchInterceptorCallbacks::iterator p = _interceptorCBs.begin(); p != _interceptorCBs.end(); ++p) { try { - for(deque<Ice::DispatchInterceptorAsyncCallbackPtr>::iterator p = _interceptorAsyncCallbackQueue.begin(); - p != _interceptorAsyncCallbackQueue.end(); ++p) +#ifdef ICE_CPP11_MAPPING + if(p->first && !p->first()) +#else + if(!(*p)->response()) +#endif { - if((*p)->exception() == false) - { - return; - } + return; } } catch(...) { - return; } - - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex); - if(!_active) - { - return; - } - _active = false; } - if(_responseHandler) - { - __exception(); - } - else - { - // - // Response has already been sent. - // - if(_os.instance()->initializationData().properties->getPropertyAsIntWithDefault("Ice.Warn.Dispatch", 1) > 0) - { - __warning("unknown exception"); - } - } + checkResponseSent(); + IncomingBase::response(true); // User thread } +#ifdef ICE_CPP11_MAPPING void -IceInternal::IncomingAsync::__response() +IceInternal::IncomingAsync::completed(exception_ptr ex) { - try + for(DispatchInterceptorCallbacks::iterator p = _interceptorCBs.begin(); p != _interceptorCBs.end(); ++p) { - if(_locator && !__servantLocatorFinished(true)) - { - return; - } - - assert(_responseHandler); - - if(_response) + try { - _observer.reply(static_cast<Int>(_os.b.size() - headerSize - 4)); - _responseHandler->sendResponse(_current.requestId, &_os, _compress, true); + if(p->second && !p->second(ex)) + { + return; + } } - else + catch(...) { - _responseHandler->sendNoResponse(); } - - _observer.detach(); - _responseHandler = 0; } - catch(const LocalException& ex) - { - _responseHandler->invokeException(_current.requestId, ex, 1, true); // Fatal invocation exception - } -} -void -IceInternal::IncomingAsync::__exception(const std::exception& exc) -{ + checkResponseSent(); try { - if(_locator && !__servantLocatorFinished(true)) - { - return; - } - - __handleException(exc, true); - } - catch(const LocalException& ex) - { - _responseHandler->invokeException(_current.requestId, ex, 1, true); // Fatal invocation exception + rethrow_exception(ex); } -} - -void -IceInternal::IncomingAsync::__exception() -{ - try + catch(const std::exception& exc) { - if(_locator && !__servantLocatorFinished(true)) - { - return; - } - - __handleException(true); + IncomingBase::exception(exc, true); // User thread } - catch(const LocalException& ex) + catch(...) { - _responseHandler->invokeException(_current.requestId, ex, 1, true); // Fatal invocation exception + IncomingBase::exception("unknown c++ exception", true); // User thread } } +#endif -bool -IceInternal::IncomingAsync::__validateResponse(bool ok) +void +IceInternal::IncomingAsync::checkResponseSent() { - // - // Only returns true if this incoming is not retriable or if all - // the interceptors return true and no response has been sent - // yet. Upon getting a true return value, the caller should send - // the response. - // - - if(_retriable) + IceUtil::Mutex::Lock sync(*globalMutex); + if(_responseSent) { - try - { - for(deque<DispatchInterceptorAsyncCallbackPtr>::iterator p = _interceptorAsyncCallbackQueue.begin(); - p != _interceptorAsyncCallbackQueue.end(); ++p) - { - if((*p)->response(ok) == false) - { - return false; - } - } - } - catch(...) - { - return false; - } - - IceUtilInternal::MutexPtrLock<IceUtil::Mutex> lock(globalMutex); - if(!_active) - { - return false; - } - _active = false; + throw ResponseSentException(__FILE__, __LINE__); } - return true; + _responseSent = true; } #ifndef ICE_CPP11_MAPPING -IceAsync::Ice::AMD_Object_ice_invoke::AMD_Object_ice_invoke(Incoming& in) : - IncomingAsync(in) +IceAsync::Ice::AMD_Object_ice_invoke::AMD_Object_ice_invoke(Incoming& in) : IncomingAsync(in) { } void IceAsync::Ice::AMD_Object_ice_invoke::ice_response(bool ok, const vector<Byte>& outEncaps) { - if(__validateResponse(ok)) + if(outEncaps.empty()) { - try - { - if(outEncaps.empty()) - { - __writeParamEncaps(0, 0, ok); - } - else - { - __writeParamEncaps(&outEncaps[0], static_cast< ::Ice::Int>(outEncaps.size()), ok); - } - } - catch(const LocalException& ex) - { - __exception(ex); - return; - } - __response(); + writeParamEncaps(0, 0, ok); + } + else + { + writeParamEncaps(&outEncaps[0], static_cast<Int>(outEncaps.size()), ok); } + completed(); } void IceAsync::Ice::AMD_Object_ice_invoke::ice_response(bool ok, const pair<const Byte*, const Byte*>& outEncaps) { - if(__validateResponse(ok)) - { - try - { - __writeParamEncaps(outEncaps.first, static_cast<Int>(outEncaps.second - outEncaps.first), ok); - } - catch(const LocalException& ex) - { - __exception(ex); - return; - } - __response(); - } + writeParamEncaps(outEncaps.first, static_cast<Int>(outEncaps.second - outEncaps.first), ok); + completed(); } #endif diff --git a/cpp/src/Ice/IncomingRequest.h b/cpp/src/Ice/IncomingRequest.h index 64082b010b7..b9e28d1df1c 100644 --- a/cpp/src/Ice/IncomingRequest.h +++ b/cpp/src/Ice/IncomingRequest.h @@ -23,15 +23,16 @@ namespace IceInternal class ICE_API IncomingRequest : public Ice::Request { public: - IncomingRequest(Incoming& in) : - _in(in) + + IncomingRequest(Incoming& in) : _in(in) { } virtual const Ice::Current& getCurrent(); - + Incoming& _in; }; + } #endif diff --git a/cpp/src/Ice/Object.cpp b/cpp/src/Ice/Object.cpp index 21166a2ff49..197c54e1918 100644 --- a/cpp/src/Ice/Object.cpp +++ b/cpp/src/Ice/Object.cpp @@ -55,10 +55,12 @@ const string __Ice__Object_ids[] = } +#ifndef ICE_CPP11_MAPPING Ice::DispatchInterceptorAsyncCallback::~DispatchInterceptorAsyncCallback() { // Out of line to avoid weak vtable } +#endif Ice::Request::~Request() { @@ -112,7 +114,7 @@ Ice::Object::ice_clone() const } #endif -DispatchStatus +bool Ice::Object::___ice_isA(Incoming& __inS, const Current& __current) { InputStream* __is = __inS.startReadParams(); @@ -124,41 +126,41 @@ Ice::Object::___ice_isA(Incoming& __inS, const Current& __current) #else bool __ret = ice_isA(__id, __current); #endif - OutputStream* __os = __inS.__startWriteParams(DefaultFormat); + OutputStream* __os = __inS.startWriteParams(); __os->write(__ret); - __inS.__endWriteParams(true); - return DispatchOK; + __inS.endWriteParams(); + return false; } -DispatchStatus +bool Ice::Object::___ice_ping(Incoming& __inS, const Current& __current) { __inS.readEmptyParams(); ice_ping(__current); - __inS.__writeEmptyParams(); - return DispatchOK; + __inS.writeEmptyParams(); + return false; } -DispatchStatus +bool Ice::Object::___ice_ids(Incoming& __inS, const Current& __current) { __inS.readEmptyParams(); vector<string> __ret = ice_ids(__current); - OutputStream* __os = __inS.__startWriteParams(DefaultFormat); + OutputStream* __os = __inS.startWriteParams(); __os->write(&__ret[0], &__ret[0] + __ret.size(), false); - __inS.__endWriteParams(true); - return DispatchOK; + __inS.endWriteParams(); + return false; } -DispatchStatus +bool Ice::Object::___ice_id(Incoming& __inS, const Current& __current) { __inS.readEmptyParams(); string __ret = ice_id(__current); - OutputStream* __os = __inS.__startWriteParams(DefaultFormat); + OutputStream* __os = __inS.startWriteParams(); __os->write(__ret, false); - __inS.__endWriteParams(true); - return DispatchOK; + __inS.endWriteParams(); + return false; } @@ -171,46 +173,45 @@ string Ice::Object::__all[] = }; -DispatchStatus +bool +#ifdef ICE_CPP11_MAPPING +Ice::Object::ice_dispatch(Request& request, std::function<bool()> r, std::function<bool(std::exception_ptr)> e) +#else Ice::Object::ice_dispatch(Request& request, const DispatchInterceptorAsyncCallbackPtr& cb) +#endif { - class PushCb + IceInternal::Incoming& in = dynamic_cast<IceInternal::IncomingRequest&>(request)._in; + in.startOver(); +#ifdef ICE_CPP11_MAPPING + if(r || e) { - public: - PushCb(IceInternal::Incoming& in, const DispatchInterceptorAsyncCallbackPtr& cb) : - _in(in), - _cb(cb) + in.push(r, e); +#else + if(cb) + { + in.push(cb); +#endif + try { - if(_cb != 0) - { - _in.push(_cb); - } + return __dispatch(in, in.getCurrent()); + in.pop(); } - - ~PushCb() + catch(...) { - if(_cb != 0) - { - _in.pop(); - } + in.pop(); + throw; } - private: - IceInternal::Incoming& _in; - const DispatchInterceptorAsyncCallbackPtr& _cb; - }; - - - IceInternal::Incoming& in = dynamic_cast<IceInternal::IncomingRequest&>(request)._in; - PushCb pusbCb(in, cb); - in.startOver(); // may raise ResponseSentException - return __dispatch(in, in.getCurrent()); + } + else + { + return __dispatch(in, in.getCurrent()); + } } -DispatchStatus +bool Ice::Object::__dispatch(Incoming& in, const Current& current) { - pair<string*, string*> r = - equal_range(__all, __all + sizeof(__all) / sizeof(string), current.operation); + pair<string*, string*> r = equal_range(__all, __all + sizeof(__all) / sizeof(string), current.operation); if(r.first == r.second) { @@ -235,10 +236,12 @@ Ice::Object::__dispatch(Incoming& in, const Current& current) { return ___ice_ping(in, current); } + default: + { + assert(false); + throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); + } } - - assert(false); - throw OperationNotExistException(__FILE__, __LINE__, current.id, current.facet, current.operation); } #ifndef ICE_CPP11_MAPPING @@ -338,7 +341,7 @@ Ice::Object::__checkMode(OperationMode expected, OperationMode received) } } -DispatchStatus +bool Ice::Blobject::__dispatch(Incoming& in, const Current& current) { const Byte* inEncaps; @@ -348,23 +351,16 @@ Ice::Blobject::__dispatch(Incoming& in, const Current& current) bool ok = ice_invoke(vector<Byte>(inEncaps, inEncaps + sz), outEncaps, current); if(outEncaps.empty()) { - in.__writeParamEncaps(0, 0, ok); + in.writeParamEncaps(0, 0, ok); } else { - in.__writeParamEncaps(&outEncaps[0], static_cast<Ice::Int>(outEncaps.size()), ok); - } - if(ok) - { - return DispatchOK; - } - else - { - return DispatchUserException; + in.writeParamEncaps(&outEncaps[0], static_cast<Ice::Int>(outEncaps.size()), ok); } + return false; } -DispatchStatus +bool Ice::BlobjectArray::__dispatch(Incoming& in, const Current& current) { pair<const Byte*, const Byte*> inEncaps; @@ -375,23 +371,16 @@ Ice::BlobjectArray::__dispatch(Incoming& in, const Current& current) bool ok = ice_invoke(inEncaps, outEncaps, current); if(outEncaps.empty()) { - in.__writeParamEncaps(0, 0, ok); + in.writeParamEncaps(0, 0, ok); } else { - in.__writeParamEncaps(&outEncaps[0], static_cast<Ice::Int>(outEncaps.size()), ok); - } - if(ok) - { - return DispatchOK; - } - else - { - return DispatchUserException; + in.writeParamEncaps(&outEncaps[0], static_cast<Ice::Int>(outEncaps.size()), ok); } + return false; } -DispatchStatus +bool Ice::BlobjectAsync::__dispatch(Incoming& in, const Current& current) { const Byte* inEncaps; @@ -399,80 +388,27 @@ Ice::BlobjectAsync::__dispatch(Incoming& in, const Current& current) in.readParamEncaps(inEncaps, sz); #ifdef ICE_CPP11_MAPPING auto async = IncomingAsync::create(in); - try - { - ice_invokeAsync(vector<Byte>(inEncaps, inEncaps + sz), - [async](bool ok, const vector<Byte>& outEncaps) - { - if(async->__validateResponse(ok)) - { - try + ice_invokeAsync(vector<Byte>(inEncaps, inEncaps + sz), + [async](bool ok, const vector<Byte>& outEncaps) { if(outEncaps.empty()) { - async->__writeParamEncaps(0, 0, ok); + async->writeParamEncaps(0, 0, ok); } else { - async->__writeParamEncaps(&outEncaps[0], static_cast< ::Ice::Int>(outEncaps.size()), ok); + async->writeParamEncaps(&outEncaps[0], static_cast<Int>(outEncaps.size()), ok); } - } - catch(const LocalException& ex) - { - async->__exception(ex); - return; - } - async->__response(); - } - }, - [async](exception_ptr e) - { - if(e) - { - try - { - rethrow_exception(e); - } - catch(const exception& ex) - { - async->ice_exception(ex); - } - } - else - { - async->ice_exception(); - } - }, - current); - } - catch(const ::std::exception& ex) - { - async->ice_exception(ex); - } - catch(...) - { - async->ice_exception(); - } + async->completed(); + }, + async->exception(), current); #else - - AMD_Object_ice_invokePtr cb = new ::IceAsync::Ice::AMD_Object_ice_invoke(in); - try - { - ice_invoke_async(cb, vector<Byte>(inEncaps, inEncaps + sz), current); - } - catch(const ::std::exception& ex) - { - cb->ice_exception(ex); - } - catch(...) - { - cb->ice_exception(); - } + ice_invoke_async(new ::IceAsync::Ice::AMD_Object_ice_invoke(in), vector<Byte>(inEncaps, inEncaps + sz), current); #endif - return DispatchAsync; + return true; } -DispatchStatus +bool Ice::BlobjectArrayAsync::__dispatch(Incoming& in, const Current& current) { pair<const Byte*, const Byte*> inEncaps; @@ -481,67 +417,15 @@ Ice::BlobjectArrayAsync::__dispatch(Incoming& in, const Current& current) inEncaps.second = inEncaps.first + sz; #ifdef ICE_CPP11_MAPPING auto async = IncomingAsync::create(in); - try - { - ice_invokeAsync(inEncaps, - [async](bool ok, const pair<const Byte*, const Byte*>& outEncaps) - { - if(async->__validateResponse(ok)) - { - try - { - async->__writeParamEncaps(outEncaps.first, static_cast<Int>(outEncaps.second - outEncaps.first), ok); - } - catch(const LocalException& ex) + ice_invokeAsync(inEncaps, + [async](bool ok, const pair<const Byte*, const Byte*>& outE) { - async->__exception(ex); - return; - } - async->__response(); - } - }, - [async](exception_ptr e) - { - if(e) - { - try - { - rethrow_exception(e); - } - catch(const exception& ex) - { - async->ice_exception(ex); - } - } - else - { - async->ice_exception(); - } - }, - current); - } - catch(const ::std::exception& ex) - { - async->ice_exception(ex); - } - catch(...) - { - async->ice_exception(); - } + async->writeParamEncaps(outE.first, static_cast<Int>(outE.second - outE.first), ok); + async->completed(); + }, + async->exception(), current); #else - AMD_Object_ice_invokePtr cb = new ::IceAsync::Ice::AMD_Object_ice_invoke(in); - try - { - ice_invoke_async(cb, inEncaps, current); - } - catch(const ::std::exception& ex) - { - cb->ice_exception(ex); - } - catch(...) - { - cb->ice_exception(); - } + ice_invoke_async(new ::IceAsync::Ice::AMD_Object_ice_invoke(in), inEncaps, current); #endif - return DispatchAsync; + return true; } diff --git a/cpp/src/Slice/Preprocessor.cpp b/cpp/src/Slice/Preprocessor.cpp index dc7c4abdf77..6a32037af44 100644 --- a/cpp/src/Slice/Preprocessor.cpp +++ b/cpp/src/Slice/Preprocessor.cpp @@ -14,6 +14,7 @@ #include <IceUtil/FileUtil.h> #include <IceUtil/UUID.h> #include <algorithm> +#include <iterator> #include <vector> #include <fstream> #include <sys/types.h> diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index ad250e25430..8ffd072bddc 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -2706,8 +2706,7 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) allOpNames.unique(); H << sp; - H << nl - << "virtual ::Ice::DispatchStatus __dispatch(::IceInternal::Incoming&, const ::Ice::Current&);"; + H << nl << "virtual bool __dispatch(::IceInternal::Incoming&, const ::Ice::Current&);"; string flatName = p->flattenedScope() + p->name() + "_all"; C << sp << nl << "namespace"; @@ -2726,8 +2725,8 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) C << eb << ';'; C << sp << nl << "}"; C << sp; - C << nl << "::Ice::DispatchStatus" << nl << scoped.substr(2) - << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)"; + C << nl << "bool"; + C << nl << scoped.substr(2) << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)"; C << sb; C << nl << "::std::pair< const ::std::string*, const ::std::string*> r = " @@ -2749,12 +2748,14 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) C << nl << "return ___" << *q << "(in, current);"; C << eb; } - C << eb; - C << sp; + C << nl << "default:"; + C << sb; C << nl << "assert(false);"; C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, " << "current.facet, current.operation);"; C << eb; + C << eb; + C << eb; // // Check if we need to generate ice_operationAttributes() @@ -3071,7 +3072,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) string paramsAMD = "(const " + classScopedAMD + '_' + name + "Ptr&, "; string paramsDeclAMD = "(const " + classScopedAMD + '_' + name + "Ptr& __cb, "; - string argsAMD = "(__cb, "; + string argsAMD = "(new IceAsync" + classScopedAMD + '_' + name + "(__inS), "; ParamDeclList inParams; ParamDeclList outParams; @@ -3165,57 +3166,37 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) if(!cl->isLocal()) { - H << nl << "::Ice::DispatchStatus ___" << name - << "(::IceInternal::Incoming&, const ::Ice::Current&)" << isConst << ';'; + H << nl << "bool ___" << name << "(::IceInternal::Incoming&, const ::Ice::Current&)" << isConst << ';'; C << sp; - C << nl << "::Ice::DispatchStatus" << nl << scope.substr(2) << "___" << name - << "(::IceInternal::Incoming& __inS" << ", const ::Ice::Current& __current)" << isConst; + C << nl << "bool" << nl << scope.substr(2) << "___" << name << "(::IceInternal::Incoming& __inS" + << ", const ::Ice::Current& __current)" << isConst; C << sb; - if(!amd) - { - ExceptionList throws = p->throws(); - throws.sort(); - throws.unique(); - - // - // Arrange exceptions into most-derived to least-derived order. If we don't - // do this, a base exception handler can appear before a derived exception - // handler, causing compiler warnings and resulting in the base exception - // being marshaled instead of the derived exception. - // + C << nl << "__checkMode(" << operationModeToString(p->mode()) << ", __current.mode);"; -#if defined(__SUNPRO_CC) - throws.sort(derivedToBaseCompare); -#else - throws.sort(Slice::DerivedToBaseCompare()); -#endif - - C << nl << "__checkMode(" << operationModeToString(p->mode()) << ", __current.mode);"; - - if(!inParams.empty()) - { - C << nl << "::Ice::InputStream* __is = __inS.startReadParams();"; - writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam); - writeUnmarshalCode(C, inParams, 0, true, TypeContextInParam); - if(p->sendsClasses(false)) - { - C << nl << "__is->readPendingValues();"; - } - C << nl << "__inS.endReadParams();"; - } - else + if(!inParams.empty()) + { + C << nl << "::Ice::InputStream* __is = __inS.startReadParams();"; + writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam); + writeUnmarshalCode(C, inParams, 0, true, TypeContextInParam); + if(p->sendsClasses(false)) { - C << nl << "__inS.readEmptyParams();"; + C << nl << "__is->readPendingValues();"; } + C << nl << "__inS.endReadParams();"; + } + else + { + C << nl << "__inS.readEmptyParams();"; + } + if(p->format() != DefaultFormat) + { + C << nl << "__inS.setFormat(" << opFormatTypeToString(p) << ");"; + } + if(!amd) + { writeAllocateCode(C, outParams, 0, true, _useWstring); - if(!throws.empty()) - { - C << nl << "try"; - C << sb; - } - C << nl; if(ret) { C << retS << " __ret = "; @@ -3223,69 +3204,24 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) C << fixKwd(name) << args << ';'; if(ret || !outParams.empty()) { - C << nl << "::Ice::OutputStream* __os = __inS.__startWriteParams(" - << opFormatTypeToString(p) << ");"; + C << nl << "::Ice::OutputStream* __os = __inS.startWriteParams();"; writeMarshalCode(C, outParams, p, true); if(p->returnsClasses(false)) { C << nl << "__os->writePendingValues();"; } - C << nl << "__inS.__endWriteParams(true);"; + C << nl << "__inS.endWriteParams();"; } else { - C << nl << "__inS.__writeEmptyParams();"; - } - C << nl << "return ::Ice::DispatchOK;"; - if(!throws.empty()) - { - C << eb; - ExceptionList::const_iterator r; - for(r = throws.begin(); r != throws.end(); ++r) - { - C << nl << "catch(const " << fixKwd((*r)->scoped()) << "& __ex)"; - C << sb; - C << nl << "__inS.__writeUserException(__ex, " << opFormatTypeToString(p) << ");"; - C << eb; - } - C << nl << "return ::Ice::DispatchUserException;"; + C << nl << "__inS.writeEmptyParams();"; } + C << nl << "return false;"; } else { - C << nl << "__checkMode(" << operationModeToString(p->mode()) << ", __current.mode);"; - - if(!inParams.empty()) - { - C << nl << "::Ice::InputStream* __is = __inS.startReadParams();"; - writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam); - writeUnmarshalCode(C, inParams, 0, true, TypeContextInParam); - if(p->sendsClasses(false)) - { - C << nl << "__is->readPendingValues();"; - } - C << nl << "__inS.endReadParams();"; - } - else - { - C << nl << "__inS.readEmptyParams();"; - } - - C << nl << classScopedAMD << '_' << name << "Ptr __cb = new IceAsync" << classScopedAMD << '_' << name - << "(__inS);"; - C << nl << "try"; - C << sb; C << nl << name << "_async" << argsAMD << ';'; - C << eb; - C << nl << "catch(const ::std::exception& __ex)"; - C << sb; - C << nl << "__cb->ice_exception(__ex);"; - C << eb; - C << nl << "catch(...)"; - C << sb; - C << nl << "__cb->ice_exception();"; - C << eb; - C << nl << "return ::Ice::DispatchAsync;"; + C << nl << "return true;"; } C << eb; } @@ -4480,22 +4416,6 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p) string paramsDecl; string args; - ExceptionList throws = p->throws(); - throws.sort(); - throws.unique(); - - // - // Arrange exceptions into most-derived to least-derived order. If we don't - // do this, a base exception handler can appear before a derived exception - // handler, causing compiler warnings and resulting in the base exception - // being marshaled instead of the derived exception. - // -#if defined(__SUNPRO_CC) - throws.sort(derivedToBaseCompare); -#else - throws.sort(Slice::DerivedToBaseCompare()); -#endif - TypePtr ret = p->returnType(); string retS = inputTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring); @@ -4547,12 +4467,6 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p) H << sp; H << nl << "virtual void ice_response(" << params << ");"; - if(!throws.empty()) - { - // COMPILERFIX: The using directive avoid compiler warnings with -Woverloaded-virtual - H << nl << "using ::IceInternal::IncomingAsync::ice_exception;"; - H << nl << "virtual void ice_exception(const ::std::exception&);"; - } H << eb << ';'; C << sp << nl << "IceAsync" << classScopedAMD << '_' << name << "::" << classNameAMD << '_' << name @@ -4563,65 +4477,25 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p) C << sb; C << eb; - C << sp << nl << "void" << nl << "IceAsync" << classScopedAMD << '_' << name << "::ice_response(" - << paramsDecl << ')'; - C << sb; - C << nl << "if(__validateResponse(true))"; + C << sp << nl << "void"; + C << nl << "IceAsync" << classScopedAMD << '_' << name << "::ice_response(" << paramsDecl << ')'; C << sb; if(ret || !outParams.empty()) { - C << nl << "try"; - C << sb; - C << nl << "::Ice::OutputStream* __os = __startWriteParams(" << opFormatTypeToString(p) << ");"; + C << nl << "::Ice::OutputStream* __os = startWriteParams();"; writeMarshalCode(C, outParams, p, false, TypeContextInParam); if(p->returnsClasses(false)) { C << nl << "__os->writePendingValues();"; } - C << nl << "__endWriteParams(true);"; - C << eb; - C << nl << "catch(const ::Ice::Exception& __ex)"; - C << sb; - C << nl << "__exception(__ex);"; - C << nl << "return;"; - C << eb; + C << nl << "endWriteParams();"; } else { - C << nl << "__writeEmptyParams();"; + C << nl << "writeEmptyParams();"; } - C << nl << "__response();"; - C << eb; + C << nl << "completed();"; C << eb; - - if(!throws.empty()) - { - C << sp << nl << "void" << nl << "IceAsync" << classScopedAMD << '_' << name - << "::ice_exception(const ::std::exception& ex)"; - C << sb; - for(ExceptionList::const_iterator r = throws.begin(); r != throws.end(); ++r) - { - C << nl; - if(r != throws.begin()) - { - C << "else "; - } - C << "if(const " << fixKwd((*r)->scoped()) << "* __ex = dynamic_cast<const " << fixKwd((*r)->scoped()) - << "*>(&ex))"; - C << sb; - C << nl <<"if(__validateResponse(false))"; - C << sb; - C << nl << "__writeUserException(*__ex, " << opFormatTypeToString(p) << ");"; - C << nl << "__response();"; - C << eb; - C << eb; - } - C << nl << "else"; - C << sb; - C << nl << "::IceInternal::IncomingAsync::ice_exception(ex);"; - C << eb; - C << eb; - } } Slice::Gen::StreamVisitor::StreamVisitor(Output& h, Output& c, const string& dllExport) : @@ -7060,11 +6934,11 @@ Slice::Gen::Cpp11InterfaceVisitor::visitClassDefEnd(const ClassDefPtr& p) string flatName = p->flattenedScope() + p->name() + "_ops"; H << sp; - H << nl << "virtual ::Ice::DispatchStatus __dispatch(::IceInternal::Incoming&, const ::Ice::Current&) override;"; + H << nl << "virtual bool __dispatch(::IceInternal::Incoming&, const ::Ice::Current&) override;"; C << sp; - C << nl << "::Ice::DispatchStatus" << nl << scoped.substr(2) - << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& c)"; + C << nl << "bool"; + C << nl << scoped.substr(2) << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& c)"; C << sb; C << nl << "::std::pair< const ::std::string*, const ::std::string*> r = " @@ -7084,11 +6958,13 @@ Slice::Gen::Cpp11InterfaceVisitor::visitClassDefEnd(const ClassDefPtr& p) C << nl << "return ___" << *q << "(in, c);"; C << eb; } - C << eb; - C << sp; + C << nl << "default:"; + C << sb; C << nl << "assert(false);"; C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, c.id, c.facet, c.operation);"; C << eb; + C << eb; + C << eb; } H << eb << ';'; @@ -7269,22 +7145,6 @@ Slice::Gen::Cpp11InterfaceVisitor::visitOperation(const OperationPtr& p) string isConst = ((p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const")) ? " const" : ""; bool amd = (cl->hasMetaData("amd") || p->hasMetaData("amd")); - ExceptionList throws = p->throws(); - throws.sort(); - throws.unique(); - - // - // Arrange exceptions into most-derived to least-derived order. If we don't - // do this, a base exception handler can appear before a derived exception - // handler, causing compiler warnings and resulting in the base exception - // being marshaled instead of the derived exception. - // -#if defined(__SUNPRO_CC) - throws.sort(derivedToBaseCompare); -#else - throws.sort(Slice::DerivedToBaseCompare()); -#endif - string deprecateSymbol = getDeprecateSymbol(p, cl); H << sp; if(!amd) @@ -7305,10 +7165,11 @@ Slice::Gen::Cpp11InterfaceVisitor::visitOperation(const OperationPtr& p) H.restoreIndent(); } - H << nl << "::Ice::DispatchStatus ___" << name << "(::IceInternal::Incoming&, const ::Ice::Current&)" << isConst << ';'; + H << nl << "bool ___" << name << "(::IceInternal::Incoming&, const ::Ice::Current&)" << isConst << ';'; C << sp; - C << nl << "::Ice::DispatchStatus" << nl << scope.substr(2) << "___" << name << "(::IceInternal::Incoming& __inS" + C << nl << "bool"; + C << nl << scope.substr(2) << "___" << name << "(::IceInternal::Incoming& __inS" << ", const ::Ice::Current& __current)" << isConst; C << sb; C << nl << "__checkMode(" << operationModeToString(p->mode(), true) << ", __current.mode);"; @@ -7328,15 +7189,14 @@ Slice::Gen::Cpp11InterfaceVisitor::visitOperation(const OperationPtr& p) { C << nl << "__inS.readEmptyParams();"; } + if(p->format() != DefaultFormat) + { + C << nl << "__inS.setFormat(" << opFormatTypeToString(p) << ");"; + } if(!amd) { writeAllocateCode(C, outParams, 0, true, _useWstring | TypeContextCpp11); - if(!throws.empty()) - { - C << nl << "try"; - C << sb; - } C << nl; if(ret) { @@ -7345,104 +7205,53 @@ Slice::Gen::Cpp11InterfaceVisitor::visitOperation(const OperationPtr& p) C << fixKwd(name) << args << ';'; if(ret || !outParams.empty()) { - C << nl << "auto __os = __inS.__startWriteParams(" << opFormatTypeToString(p) << ");"; + C << nl << "auto __os = __inS.startWriteParams();"; writeMarshalCode(C, outParams, p, true, TypeContextCpp11); if(p->returnsClasses(false)) { C << nl << "__os->writePendingValues();"; } - C << nl << "__inS.__endWriteParams(true);"; + C << nl << "__inS.endWriteParams();"; } else { - C << nl << "__inS.__writeEmptyParams();"; - } - C << nl << "return ::Ice::DispatchOK;"; - if(!throws.empty()) - { - C << eb; - ExceptionList::const_iterator r; - for(r = throws.begin(); r != throws.end(); ++r) - { - C << nl << "catch(const " << fixKwd((*r)->scoped()) << "& __ex)"; - C << sb; - C << nl << "__inS.__writeUserException(__ex, " << opFormatTypeToString(p) << ");"; - C << eb; - } - C << nl << "return ::Ice::DispatchUserException;"; + C << nl << "__inS.writeEmptyParams();"; } + C << nl << "return false;"; } else { C << nl << "auto inS = ::IceInternal::IncomingAsync::create(__inS);"; - C << nl << "auto __exception = [inS](::std::exception_ptr e)"; - C << sb; - C << nl << "try"; - C << sb; - C << nl << "std::rethrow_exception(e);"; - C << eb; - - for(ExceptionList::const_iterator r = throws.begin(); r != throws.end(); ++r) - { - C << nl << "catch(const " << fixKwd((*r)->scoped()) << "& __ex)"; - C << sb; - C << nl <<"if(inS->__validateResponse(false))"; - C << sb; - C << nl << "inS->__writeUserException(__ex, " << opFormatTypeToString(p) << ");"; - C << nl << "inS->__response();"; - C << eb; - C << eb; - } - - C << nl << "catch(const ::std::exception& __ex)"; - C << sb; - C << nl << "inS->ice_exception(__ex);"; - C << eb; - C << nl << "catch(...)"; - C << sb; - C << nl << "inS->ice_exception();"; - C << eb; - C << eb << ";"; - - C << nl << "try"; - C << sb; C << nl << name << "Async("; C.useCurrentPosAsIndent(); if(!argsAMD.empty()) { - C << argsAMD << ","; - C << nl; + C << argsAMD << ", "; } - C << "[inS](" << responseParamsDecl << ")"; - C << sb; - C << nl << "if(inS->__validateResponse(true))"; - C << sb; if(ret || !outParams.empty()) { - C << nl << "auto __os = inS->__startWriteParams(" << opFormatTypeToString(p) << ");"; + //C << "inS->response<" << responseParams << ">(), "; + C << nl << "[inS](" << responseParamsDecl << ")"; + C << sb; + C << nl << "auto __os = inS->startWriteParams();"; writeMarshalCode(C, outParams, p, true, TypeContextCpp11); if(p->returnsClasses(false)) { C << nl << "__os->writePendingValues();"; } - C << nl << "inS->__endWriteParams(true);"; + C << nl << "inS->endWriteParams();"; + C << nl << "inS->completed();"; + C << eb; + C << ", "; } else { - C << nl << "inS->__writeEmptyParams();"; + C << "inS->response(), "; } - C << nl << "inS->__response();"; - C << eb; - C << eb << ","; - C << nl << "__exception, __current);"; + C << "inS->exception(), __current);"; C.restoreIndent(); - C << eb; - C << nl << "catch(...)"; - C << sb; - C << nl << "__exception(std::current_exception());"; - C << eb; - C << nl << "return ::Ice::DispatchAsync;"; + C << nl << "return true;"; } C << eb; } diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp index fcdcf250291..5fa82827c4f 100644 --- a/cpp/src/slice2cs/Gen.cpp +++ b/cpp/src/slice2cs/Gen.cpp @@ -4015,8 +4015,21 @@ Slice::Gen::ResultVisitor::visitOperation(const OperationPtr& p) _out << nl << "os__.endEncapsulation();"; _out << eb; _out << sp; - _out << nl << "public Ice.OutputStream getOutputStream()"; + _out << nl << "public Ice.OutputStream getOutputStream(Ice.Current current)"; _out << sb; + _out << nl << "if(os__ == null)"; + _out << sb; + _out << nl << "return new " << name << spar; + if(ret) + { + _out << writeValue(ret); + } + for(ParamDeclList::const_iterator i = outParams.begin(); i != outParams.end(); ++i) + { + _out << writeValue((*i)->type()); + } + _out << "current" << epar << ".getOutputStream(current);"; + _out << eb; _out << nl << "return os__;"; _out << eb; _out << sp; diff --git a/cpp/test/Ice/exceptions/AllTests.cpp b/cpp/test/Ice/exceptions/AllTests.cpp index 990f735a805..46c3ce7ae9a 100644 --- a/cpp/test/Ice/exceptions/AllTests.cpp +++ b/cpp/test/Ice/exceptions/AllTests.cpp @@ -1137,6 +1137,7 @@ allTests(const Ice::CommunicatorPtr& communicator) try { thrower->throwAfterException(); + test(false); } catch(const A&) { @@ -1170,7 +1171,7 @@ allTests(const Ice::CommunicatorPtr& communicator) test(false); } } - + { auto f = thrower->throwAorDasAorDAsync(1); try @@ -1187,7 +1188,7 @@ allTests(const Ice::CommunicatorPtr& communicator) test(false); } } - + { auto f = thrower->throwAorDasAorDAsync(-1); try @@ -1260,7 +1261,7 @@ allTests(const Ice::CommunicatorPtr& communicator) test(false); } } - + // // repeat with callback API and no exception callback // @@ -1278,7 +1279,7 @@ allTests(const Ice::CommunicatorPtr& communicator) }); sent.get_future().get(); // Wait for sent } - + { promise<bool> sent; thrower->throwAorDasAorDAsync(1, @@ -1293,7 +1294,7 @@ allTests(const Ice::CommunicatorPtr& communicator) }); sent.get_future().get(); // Wait for sent } - + { promise<bool> sent; thrower->throwAorDasAorDAsync(-1, diff --git a/cpp/test/Ice/interceptor/AMDInterceptorI.cpp b/cpp/test/Ice/interceptor/AMDInterceptorI.cpp index 621d939e348..f790db8c6a0 100644 --- a/cpp/test/Ice/interceptor/AMDInterceptorI.cpp +++ b/cpp/test/Ice/interceptor/AMDInterceptorI.cpp @@ -15,24 +15,24 @@ using namespace std; AMDInterceptorI::AMDInterceptorI(const Ice::ObjectPtr& servant) : - InterceptorI(servant), - _defaultCb(new DispatchInterceptorAsyncCallbackI(*this)), - _actualStatus(Ice::DispatchAsync) - + InterceptorI(servant) +#ifndef ICE_CPP11_MAPPING + , _defaultCb(new DispatchInterceptorAsyncCallbackI(*this)) +#endif { } - -Ice::DispatchStatus + +bool AMDInterceptorI::dispatch(Ice::Request& request) { +#ifndef ICE_CPP11_MAPPING class CallbackI : public Ice::DispatchInterceptorAsyncCallback { public: - - virtual bool response(bool ok) + + virtual bool response() { - test(ok); return false; } @@ -51,48 +51,76 @@ AMDInterceptorI::dispatch(Ice::Request& request) return false; } }; - + Ice::DispatchInterceptorAsyncCallbackPtr cb = ICE_MAKE_SHARED(CallbackI); +#endif Ice::Current& current = const_cast<Ice::Current&>(request.getCurrent()); _lastOperation = current.operation; - - Ice::DispatchInterceptorAsyncCallbackPtr cb = ICE_MAKE_SHARED(CallbackI); if(_lastOperation == "amdAddWithRetry") { for(int i = 0; i < 10; ++i) { - _lastStatus = _servant->ice_dispatch(request, cb); - test(_lastStatus == Ice::DispatchAsync); + try + { +#ifdef ICE_CPP11_MAPPING + _lastStatus = _servant->ice_dispatch(request, nullptr, [](exception_ptr ex) { + try + { + rethrow_exception(ex); + } + catch(Test::RetryException&) + { + } + catch(...) + { + test(false); + } + return false; + }); +#else + _lastStatus = _servant->ice_dispatch(request, cb); +#endif + test(_lastStatus); + } + catch(const Test::RetryException&) + { + // + // Expected, retry + // + } } - + current.ctx["retry"] = "no"; } - + +#ifdef ICE_CPP11_MAPPING + _lastStatus = _servant->ice_dispatch(request, []() { return true; }, [this](exception_ptr ex) { + try + { + rethrow_exception(ex); + } + catch(const IceUtil::Exception& ex) + { + setException(ex); + } + catch(...) + { + test(false); + } + return true; + }); +#else _lastStatus = _servant->ice_dispatch(request, _defaultCb); +#endif return _lastStatus; } -void -AMDInterceptorI::setActualStatus(Ice::DispatchStatus status) -{ - IceUtil::Mutex::Lock lock(_mutex); - _actualStatus = status; -} - -void -AMDInterceptorI::setActualStatus(const IceUtil::Exception& e) +void +AMDInterceptorI::setException(const IceUtil::Exception& e) { IceUtil::Mutex::Lock lock(_mutex); ICE_SET_EXCEPTION_FROM_CLONE(_exception, e.ice_clone()); - _actualStatus = Ice::DispatchAsync; -} - -Ice::DispatchStatus -AMDInterceptorI::getActualStatus() const -{ - IceUtil::Mutex::Lock lock(_mutex); - return _actualStatus; } IceUtil::Exception* @@ -102,42 +130,40 @@ AMDInterceptorI::getException() const return _exception.get(); } -void +void AMDInterceptorI::clear() { InterceptorI::clear(); IceUtil::Mutex::Lock lock(_mutex); - _actualStatus = Ice::DispatchAsync; _exception.reset(); } - +#ifndef ICE_CPP11_MAPPING DispatchInterceptorAsyncCallbackI::DispatchInterceptorAsyncCallbackI(AMDInterceptorI& interceptor) : _interceptor(interceptor) { } -bool -DispatchInterceptorAsyncCallbackI::response(bool ok) +bool +DispatchInterceptorAsyncCallbackI::response() { - _interceptor.setActualStatus(ok ? Ice::DispatchOK : Ice::DispatchUserException); return true; } -bool +bool DispatchInterceptorAsyncCallbackI::exception(const std::exception& ex) { // // Only Ice exceptions are raised by this test // const IceUtil::Exception& ue = dynamic_cast<const IceUtil::Exception&>(ex); - _interceptor.setActualStatus(ue); + _interceptor.setException(ue); return true; } - -bool + +bool DispatchInterceptorAsyncCallbackI::exception() { // @@ -146,3 +172,4 @@ DispatchInterceptorAsyncCallbackI::exception() test(false); return true; } +#endif
\ No newline at end of file diff --git a/cpp/test/Ice/interceptor/AMDInterceptorI.h b/cpp/test/Ice/interceptor/AMDInterceptorI.h index 935b179b0ba..fea7b042f39 100644 --- a/cpp/test/Ice/interceptor/AMDInterceptorI.h +++ b/cpp/test/Ice/interceptor/AMDInterceptorI.h @@ -18,39 +18,39 @@ class AMDInterceptorI : public InterceptorI public: AMDInterceptorI(const Ice::ObjectPtr&); - - virtual Ice::DispatchStatus dispatch(Ice::Request&); - + + virtual bool dispatch(Ice::Request&); + virtual void clear(); - Ice::DispatchStatus getActualStatus() const; IceUtil::Exception* getException() const; + void setException(const IceUtil::Exception&); - void setActualStatus(Ice::DispatchStatus); - void setActualStatus(const IceUtil::Exception&); - private: +#ifndef ICE_CPP11_MAPPING Ice::DispatchInterceptorAsyncCallbackPtr _defaultCb; - Ice::DispatchStatus _actualStatus; +#endif IceUtil::UniquePtr<IceUtil::Exception> _exception; - + IceUtil::Mutex _mutex; }; ICE_DEFINE_PTR(AMDInterceptorIPtr, AMDInterceptorI); +#ifndef ICE_CPP11_MAPPING class DispatchInterceptorAsyncCallbackI : public Ice::DispatchInterceptorAsyncCallback { public: DispatchInterceptorAsyncCallbackI(AMDInterceptorI&); - virtual bool response(bool); + virtual bool response(); virtual bool exception(const std::exception&); virtual bool exception(); private: AMDInterceptorI& _interceptor; }; +#endif #endif diff --git a/cpp/test/Ice/interceptor/Client.cpp b/cpp/test/Ice/interceptor/Client.cpp index c49abdf807e..d77b076c157 100644 --- a/cpp/test/Ice/interceptor/Client.cpp +++ b/cpp/test/Ice/interceptor/Client.cpp @@ -200,21 +200,21 @@ Client::run(const Test::MyObjectPrxPtr& prx, const InterceptorIPtr& interceptor) test(interceptor->getLastOperation().empty()); prx->ice_ping(); test(interceptor->getLastOperation() == "ice_ping"); - test(interceptor->getLastStatus() == Ice::DispatchOK); + test(!interceptor->getLastStatus()); string typeId = prx->ice_id(); test(interceptor->getLastOperation() == "ice_id"); - test(interceptor->getLastStatus() == Ice::DispatchOK); + test(!interceptor->getLastStatus()); test(prx->ice_isA(typeId)); test(interceptor->getLastOperation() == "ice_isA"); - test(interceptor->getLastStatus() == Ice::DispatchOK); + test(!interceptor->getLastStatus()); test(prx->add(33, 12) == 45); test(interceptor->getLastOperation() == "add"); - test(interceptor->getLastStatus() == Ice::DispatchOK); + test(!interceptor->getLastStatus()); cout << "ok" << endl; cout << "testing retry... " << flush; test(prx->addWithRetry(33, 12) == 45); test(interceptor->getLastOperation() == "addWithRetry"); - test(interceptor->getLastStatus() == Ice::DispatchOK); + test(!interceptor->getLastStatus()); cout << "ok" << endl; cout << "testing user exception... " << flush; try @@ -227,7 +227,7 @@ Client::run(const Test::MyObjectPrxPtr& prx, const InterceptorIPtr& interceptor) // expected } test(interceptor->getLastOperation() == "badAdd"); - test(interceptor->getLastStatus() == Ice::DispatchUserException); + test(!interceptor->getLastStatus()); cout << "ok" << endl; cout << "testing ONE... " << flush; @@ -268,7 +268,7 @@ Client::run(const Test::MyObjectPrxPtr& prx, const InterceptorIPtr& interceptor) cout << "testing simple AMD... " << flush; test(prx->amdAdd(33, 12) == 45); test(interceptor->getLastOperation() == "amdAdd"); - test(interceptor->getLastStatus() == Ice::DispatchAsync); + test(interceptor->getLastStatus()); cout << "ok" << endl; return EXIT_SUCCESS; @@ -281,14 +281,12 @@ Client::runAmd(const Test::MyObjectPrxPtr& prx, const AMDInterceptorIPtr& interc test(interceptor->getLastOperation().empty()); test(prx->amdAdd(33, 12) == 45); test(interceptor->getLastOperation() == "amdAdd"); - test(interceptor->getLastStatus() == Ice::DispatchAsync); - test(interceptor->getActualStatus() == Ice::DispatchOK); + test(interceptor->getLastStatus()); cout << "ok" << endl; cout << "testing retry... " << flush; test(prx->amdAddWithRetry(33, 12) == 45); test(interceptor->getLastOperation() == "amdAddWithRetry"); - test(interceptor->getLastStatus() == Ice::DispatchAsync); - test(interceptor->getActualStatus() == Ice::DispatchOK); + test(interceptor->getLastStatus()); cout << "ok" << endl; cout << "testing user exception... " << flush; try @@ -301,8 +299,7 @@ Client::runAmd(const Test::MyObjectPrxPtr& prx, const AMDInterceptorIPtr& interc // expected } test(interceptor->getLastOperation() == "amdBadAdd"); - test(interceptor->getLastStatus() == Ice::DispatchAsync); - test(interceptor->getActualStatus() == Ice::DispatchUserException); + test(interceptor->getLastStatus()); cout << "ok" << endl; cout << "testing ONE... " << flush; interceptor->clear(); @@ -316,9 +313,8 @@ Client::runAmd(const Test::MyObjectPrxPtr& prx, const AMDInterceptorIPtr& interc // expected } test(interceptor->getLastOperation() == "amdNotExistAdd"); - test(interceptor->getLastStatus() == Ice::DispatchAsync); - test(interceptor->getActualStatus() == Ice::DispatchAsync); - + test(interceptor->getLastStatus()); + test(dynamic_cast<Ice::ObjectNotExistException*>(interceptor->getException()) != 0); cout << "ok" << endl; @@ -338,8 +334,7 @@ Client::runAmd(const Test::MyObjectPrxPtr& prx, const AMDInterceptorIPtr& interc test(prx->ice_isCollocationOptimized()); } test(interceptor->getLastOperation() == "amdBadSystemAdd"); - test(interceptor->getLastStatus() == Ice::DispatchAsync); - test(interceptor->getActualStatus() == Ice::DispatchAsync); + test(interceptor->getLastStatus()); test(dynamic_cast<MySystemException*>(interceptor->getException()) != 0); cout << "ok" << endl; return EXIT_SUCCESS; diff --git a/cpp/test/Ice/interceptor/InterceptorI.cpp b/cpp/test/Ice/interceptor/InterceptorI.cpp index 571dd555f64..601920483ab 100644 --- a/cpp/test/Ice/interceptor/InterceptorI.cpp +++ b/cpp/test/Ice/interceptor/InterceptorI.cpp @@ -15,12 +15,12 @@ using namespace std; InterceptorI::InterceptorI(const Ice::ObjectPtr& servant) : _servant(servant), - _lastStatus(Ice::DispatchAsync) + _lastStatus(false) { } -Ice::DispatchStatus +bool InterceptorI::dispatch(Ice::Request& request) { Ice::Current& current = const_cast<Ice::Current&>(request.getCurrent()); @@ -49,7 +49,7 @@ InterceptorI::dispatch(Ice::Request& request) return _lastStatus; } -Ice::DispatchStatus +bool InterceptorI::getLastStatus() const { return _lastStatus; @@ -64,6 +64,6 @@ InterceptorI::getLastOperation() const void InterceptorI::clear() { - _lastStatus = Ice::DispatchAsync; + _lastStatus = false; _lastOperation = ""; } diff --git a/cpp/test/Ice/interceptor/InterceptorI.h b/cpp/test/Ice/interceptor/InterceptorI.h index f4624f255eb..4c2c3ff7ebf 100644 --- a/cpp/test/Ice/interceptor/InterceptorI.h +++ b/cpp/test/Ice/interceptor/InterceptorI.h @@ -18,18 +18,18 @@ class InterceptorI : public Ice::DispatchInterceptor public: InterceptorI(const Ice::ObjectPtr&); - - virtual Ice::DispatchStatus dispatch(Ice::Request& request); - - Ice::DispatchStatus getLastStatus() const; + + virtual bool dispatch(Ice::Request& request); + + bool getLastStatus() const; const std::string& getLastOperation() const; - + virtual void clear(); protected: const Ice::ObjectPtr _servant; std::string _lastOperation; - Ice::DispatchStatus _lastStatus; + bool _lastStatus; }; ICE_DEFINE_PTR(InterceptorIPtr, InterceptorI); diff --git a/cpp/test/Ice/interceptor/MyObjectI.cpp b/cpp/test/Ice/interceptor/MyObjectI.cpp index 4e9c7c1f524..f3879f9be2b 100644 --- a/cpp/test/Ice/interceptor/MyObjectI.cpp +++ b/cpp/test/Ice/interceptor/MyObjectI.cpp @@ -109,8 +109,14 @@ MyObjectI::amdAddWithRetryAsync(int x, thread t( [x, y, response]() { - this_thread::sleep_for(chrono::milliseconds(10)); - response(x + y); + try + { + this_thread::sleep_for(chrono::milliseconds(10)); + response(x + y); + } + catch(Ice::ResponseSentException&) + { + } }); t.detach(); diff --git a/cpp/test/Ice/proxy/Server.cpp b/cpp/test/Ice/proxy/Server.cpp index c0a9a8761c5..ac9b496ae68 100644 --- a/cpp/test/Ice/proxy/Server.cpp +++ b/cpp/test/Ice/proxy/Server.cpp @@ -49,4 +49,3 @@ main(int argc, char* argv[]) return EXIT_FAILURE; } } - diff --git a/cpp/test/Ice/slicing/objects/Test.ice b/cpp/test/Ice/slicing/objects/Test.ice index 75325ea877b..a20bde62928 100644 --- a/cpp/test/Ice/slicing/objects/Test.ice +++ b/cpp/test/Ice/slicing/objects/Test.ice @@ -66,7 +66,7 @@ exception DerivedException extends BaseException D1 pd1; }; -class Forward; /* Forward-declared class defined in another compilation unit */ +class Forward; class PBase { diff --git a/cpp/test/Ice/slicing/objects/TestAMD.ice b/cpp/test/Ice/slicing/objects/TestAMD.ice index 1212dd3a930..bb0949bf705 100644 --- a/cpp/test/Ice/slicing/objects/TestAMD.ice +++ b/cpp/test/Ice/slicing/objects/TestAMD.ice @@ -66,7 +66,7 @@ exception DerivedException extends BaseException D1 pd1; }; -class Forward; /* Forward-declared class defined in another compilation unit */ +class Forward; class PBase { |