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 /cs/src/Ice/ConnectRequestHandler.cs | |
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 'cs/src/Ice/ConnectRequestHandler.cs')
-rw-r--r-- | cs/src/Ice/ConnectRequestHandler.cs | 76 |
1 files changed, 50 insertions, 26 deletions
diff --git a/cs/src/Ice/ConnectRequestHandler.cs b/cs/src/Ice/ConnectRequestHandler.cs index a5953343b10..b516af9a4e7 100644 --- a/cs/src/Ice/ConnectRequestHandler.cs +++ b/cs/src/Ice/ConnectRequestHandler.cs @@ -36,19 +36,24 @@ namespace IceInternal internal Ice.AsyncCallback sentCallback = null; } - public RequestHandler connect() + public RequestHandler connect(Ice.ObjectPrxHelperBase proxy) { - Ice.ObjectPrxHelperBase proxy = _proxy; - try + // + // Initiate the connection if connect() is called by the proxy that + // created the handler. + // + if(Object.ReferenceEquals(proxy, _proxy)) { _reference.getConnection(this); + } + try + { lock(this) { if(!initialized()) { - // The proxy request handler will be updated when the connection is set. - _updateRequestHandler = true; + _proxies.Add(proxy); return this; } } @@ -59,11 +64,15 @@ namespace IceInternal throw ex; } - Debug.Assert(_connection != null); - - RequestHandler handler = new ConnectionRequestHandler(_reference, _connection, _compress); - proxy.setRequestHandler__(this, handler); - return handler; + if(_connectionRequestHandler != null) + { + proxy.setRequestHandler__(this, _connectionRequestHandler); + return _connectionRequestHandler; + } + else + { + return this; + } } public RequestHandler update(RequestHandler previousHandler, RequestHandler newHandler) @@ -276,13 +285,17 @@ namespace IceInternal { Debug.Assert(!_initialized && _exception == null); _exception = ex; + _proxies.Clear(); _proxy = null; // 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. - // + try + { + _reference.getInstance().requestHandlerFactory().removeRequestHandler(_reference, this); + } + catch(Ice.CommunicatorDestroyedException) + { + // Ignore + } flushRequestsWithException(); System.Threading.Monitor.PulseAll(this); @@ -313,7 +326,6 @@ namespace IceInternal _batchRequestInProgress = false; _batchRequestsSize = Protocol.requestBatchHdr.Length; _batchStream = new BasicStream(@ref.getInstance(), Ice.Util.currentProtocolEncoding, _batchAutoFlush); - _updateRequestHandler = false; } private bool initialized() @@ -424,17 +436,18 @@ namespace IceInternal } // - // We've finished sending the queued requests and the request handler now send - // 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. - // - // NOTE: _updateRequestHandler is immutable once _flushing = true + // 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 == null) + if(_reference.getCacheConnection() && _exception == null) { - _proxy.setRequestHandler__(this, new ConnectionRequestHandler(_reference, _connection, _compress)); + _connectionRequestHandler = new ConnectionRequestHandler(_reference, _connection, _compress); + foreach(Ice.ObjectPrxHelperBase prx in _proxies) + { + prx.setRequestHandler__(this, _connectionRequestHandler); + } } lock(this) @@ -445,6 +458,15 @@ namespace IceInternal _initialized = true; _flushing = false; } + try + { + _reference.getInstance().requestHandlerFactory().removeRequestHandler(_reference, this); + } + catch(Ice.CommunicatorDestroyedException) + { + // Ignore + } + _proxies.Clear(); _proxy = null; // Break cyclic reference count. System.Threading.Monitor.PulseAll(this); } @@ -471,6 +493,7 @@ namespace IceInternal private bool _response; private Ice.ObjectPrxHelperBase _proxy; + private List<Ice.ObjectPrxHelperBase> _proxies = new List<Ice.ObjectPrxHelperBase>(); private bool _batchAutoFlush; @@ -484,6 +507,7 @@ namespace IceInternal private bool _batchRequestInProgress; private int _batchRequestsSize; private BasicStream _batchStream; - private bool _updateRequestHandler; + + private RequestHandler _connectionRequestHandler; } } |