summaryrefslogtreecommitdiff
path: root/cs/src/Ice/ConnectRequestHandler.cs
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2014-10-22 16:33:13 +0200
committerBenoit Foucher <benoit@zeroc.com>2014-10-22 16:33:13 +0200
commitd8da15a2d803da81b76568d0c8f620f8ed26d0fa (patch)
treef193067905624d61e0e8a3e6cd7d2498b9bf1873 /cs/src/Ice/ConnectRequestHandler.cs
parentFixed demo dist to allow gradle build of java demos (diff)
downloadice-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.cs76
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;
}
}