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/src | |
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/src')
-rw-r--r-- | cpp/src/Ice/DispatchInterceptor.cpp | 26 | ||||
-rw-r--r-- | cpp/src/Ice/Incoming.cpp | 458 | ||||
-rw-r--r-- | cpp/src/Ice/IncomingAsync.cpp | 288 | ||||
-rw-r--r-- | cpp/src/Ice/IncomingRequest.h | 7 | ||||
-rw-r--r-- | cpp/src/Ice/Object.cpp | 270 | ||||
-rw-r--r-- | cpp/src/Slice/Preprocessor.cpp | 1 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 335 | ||||
-rw-r--r-- | cpp/src/slice2cs/Gen.cpp | 15 |
8 files changed, 478 insertions, 922 deletions
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; |