diff options
author | Benoit Foucher <benoit@zeroc.com> | 2014-10-22 16:33:13 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2014-10-22 16:33:13 +0200 |
commit | d8da15a2d803da81b76568d0c8f620f8ed26d0fa (patch) | |
tree | f193067905624d61e0e8a3e6cd7d2498b9bf1873 /cpp/src/Ice/ConnectRequestHandler.cpp | |
parent | Fixed demo dist to allow gradle build of java demos (diff) | |
download | ice-d8da15a2d803da81b76568d0c8f620f8ed26d0fa.tar.bz2 ice-d8da15a2d803da81b76568d0c8f620f8ed26d0fa.tar.xz ice-d8da15a2d803da81b76568d0c8f620f8ed26d0fa.zip |
Fixed ICE-3490: guarantee invocation serialization for proxies which are equal
Diffstat (limited to 'cpp/src/Ice/ConnectRequestHandler.cpp')
-rw-r--r-- | cpp/src/Ice/ConnectRequestHandler.cpp | 72 |
1 files changed, 49 insertions, 23 deletions
diff --git a/cpp/src/Ice/ConnectRequestHandler.cpp b/cpp/src/Ice/ConnectRequestHandler.cpp index a1458484a57..55f1c508d5a 100644 --- a/cpp/src/Ice/ConnectRequestHandler.cpp +++ b/cpp/src/Ice/ConnectRequestHandler.cpp @@ -9,6 +9,7 @@ #include <Ice/ConnectRequestHandler.h> #include <Ice/ConnectionRequestHandler.h> +#include <Ice/RequestHandlerFactory.h> #include <Ice/Instance.h> #include <Ice/Proxy.h> #include <Ice/ConnectionI.h> @@ -31,8 +32,7 @@ ConnectRequestHandler::ConnectRequestHandler(const ReferencePtr& ref, const Ice: _flushing(false), _batchRequestInProgress(false), _batchRequestsSize(sizeof(requestBatchHdr)), - _batchStream(ref->getInstance().get(), Ice::currentProtocolEncoding, _batchAutoFlush), - _updateRequestHandler(false) + _batchStream(ref->getInstance().get(), Ice::currentProtocolEncoding, _batchAutoFlush) { } @@ -41,17 +41,23 @@ ConnectRequestHandler::~ConnectRequestHandler() } RequestHandlerPtr -ConnectRequestHandler::connect() +ConnectRequestHandler::connect(const Ice::ObjectPrx& proxy) { - Ice::ObjectPrx proxy = _proxy; - try + // + // Initiate the connection if connect() is called by the proxy that + // created the handler. + // + if(proxy.get() == _proxy.get()) { _reference->getConnection(this); + } + try + { Lock sync(*this); if(!initialized()) { - _updateRequestHandler = true; // The proxy request handler will be updated when the connection is set. + _proxies.push_back(proxy); return this; } } @@ -61,11 +67,15 @@ ConnectRequestHandler::connect() throw; } - assert(_connection); - - RequestHandlerPtr handler = new ConnectionRequestHandler(_reference, _connection, _compress); - proxy->__setRequestHandler(this, handler); - return handler; + if(_connectionRequestHandler) + { + proxy->__setRequestHandler(this, _connectionRequestHandler); + return _connectionRequestHandler; + } + else + { + return this; + } } RequestHandlerPtr @@ -335,15 +345,19 @@ ConnectRequestHandler::setException(const Ice::LocalException& ex) Lock sync(*this); assert(!_initialized && !_exception.get()); _exception.reset(ex.ice_clone()); + _proxies.clear(); _proxy = 0; // Break cyclic reference count. - // - // If some requests were queued, we notify them of the failure. This is done from a thread - // from the client thread pool since this will result in ice_exception callbacks to be - // called. - // flushRequestsWithException(); + try + { + _reference->getInstance()->requestHandlerFactory()->removeRequestHandler(_reference, this); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignore + } notifyAll(); } @@ -467,15 +481,18 @@ ConnectRequestHandler::flushRequests() } // - // We've finished sending the queued requests and the request handler now sends - // the requests over the connection directly. It's time to substitute the - // request handler of the proxy with the more efficient connection request - // handler which does not have any synchronization. This also breaks the cyclic - // reference count with the proxy. + // If we aren't caching the connection, don't bother creating a + // connection request handler. Otherwise, update the proxies + // request handler to use the more efficient connection request + // handler. // - if(_updateRequestHandler && !_exception.get()) + if(_reference->getCacheConnection() && !_exception.get()) { - _proxy->__setRequestHandler(this, new ConnectionRequestHandler(_reference, _connection, _compress)); + _connectionRequestHandler = new ConnectionRequestHandler(_reference, _connection, _compress); + for(vector<Ice::ObjectPrx>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p) + { + (*p)->__setRequestHandler(this, _connectionRequestHandler); + } } { @@ -486,6 +503,15 @@ ConnectRequestHandler::flushRequests() _initialized = true; _flushing = false; } + try + { + _reference->getInstance()->requestHandlerFactory()->removeRequestHandler(_reference, this); + } + catch(const Ice::CommunicatorDestroyedException&) + { + // Ignore + } + _proxies.clear(); _proxy = 0; // Break cyclic reference count. notifyAll(); } |