From 4fa256d3d27adffcc6529136cad904f0fbd490b0 Mon Sep 17 00:00:00 2001 From: Benoit Foucher Date: Thu, 25 Aug 2016 11:28:20 +0200 Subject: 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) --- cpp/src/Ice/IncomingAsync.cpp | 288 +++++++++++------------------------------- 1 file changed, 76 insertions(+), 212 deletions(-) (limited to 'cpp/src/Ice/IncomingAsync.cpp') 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 IceInternal::IncomingAsync::create(Incoming& in) { - IncomingAsyncPtr self = make_shared(in); - if(in.isRetriable()) - { - in.setActive(self->shared_from_this()); - } - return self; + auto async = make_shared(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 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::iterator p = _interceptorAsyncCallbackQueue.begin(); - p != _interceptorAsyncCallbackQueue.end(); ++p) + if(!(*p)->exception()) { - if((*p)->exception(ex) == false) - { - return; - } + return; } } catch(...) { - return; } - - IceUtilInternal::MutexPtrLock 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::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 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(_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::iterator p = _interceptorAsyncCallbackQueue.begin(); - p != _interceptorAsyncCallbackQueue.end(); ++p) - { - if((*p)->response(ok) == false) - { - return false; - } - } - } - catch(...) - { - return false; - } - - IceUtilInternal::MutexPtrLock 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& 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(outEncaps.size()), ok); } + completed(); } void IceAsync::Ice::AMD_Object_ice_invoke::ice_response(bool ok, const pair& outEncaps) { - if(__validateResponse(ok)) - { - try - { - __writeParamEncaps(outEncaps.first, static_cast(outEncaps.second - outEncaps.first), ok); - } - catch(const LocalException& ex) - { - __exception(ex); - return; - } - __response(); - } + writeParamEncaps(outEncaps.first, static_cast(outEncaps.second - outEncaps.first), ok); + completed(); } #endif -- cgit v1.2.3