public ConnectRequestHandler(Reference @ref, Ice.ObjectPrx proxy, Ice.ObjectDelM_ del) { _reference = @ref; _response = _reference.getMode() == Reference.Mode.ModeTwoway; _proxy = (Ice.ObjectPrxHelperBase)proxy; _delegate = del; _batchAutoFlush = @ref.getInstance().initializationData().properties.getPropertyAsIntWithDefault( "Ice.BatchAutoFlush", 1) > 0 ? true : false; _initialized = false; _flushing = false; _batchRequestInProgress = false; _batchRequestsSize = Protocol.requestBatchHdr.Length; _batchStream = new BasicStream(@ref.getInstance(), _batchAutoFlush); _updateRequestHandler = false; }
public ConnectRequestHandler(Reference @ref, Ice.ObjectPrx proxy, Ice.ObjectDelM_ del) { _reference = @ref; _response = _reference.getMode() == Reference.Mode.ModeTwoway; _proxy = (Ice.ObjectPrxHelperBase)proxy; _delegate = del; _batchAutoFlush = @ref.getInstance().initializationData().properties.getPropertyAsIntWithDefault( "Ice.BatchAutoFlush", 1) > 0 ? true : false; _initialized = false; _flushing = false; _batchRequestInProgress = false; _batchRequestsSize = Protocol.requestBatchHdr.Length; _batchStream = new BasicStream(@ref.getInstance(), Ice.Util.currentProtocolEncoding, _batchAutoFlush); _updateRequestHandler = false; }
private void flushRequests() { _m.Lock(); try { Debug.Assert(_connection != null && !_initialized); while(_batchRequestInProgress) { _m.Wait(); } // // We set the _flushing flag to true to prevent any additional queuing. Callers // might block for a little while as the queued requests are being sent but this // shouldn't be an issue as the request sends are non-blocking. // _flushing = true; } finally { _m.Unlock(); } LinkedList<Request> sentCallbacks = new LinkedList<Request>(); try { LinkedListNode<Request> p = _requests.First; // _requests is immutable when _flushing = true while(p != null) { Request request = p.Value; if(request.@out != null) { if(_connection.sendAsyncRequest(request.@out, _compress, _response, out request.sentCallback)) { if(request.sentCallback != null) { sentCallbacks.AddLast(request); } } } else if(request.batchOut != null) { if(_connection.flushAsyncBatchRequests(request.batchOut, out request.sentCallback)) { if(request.sentCallback != null) { sentCallbacks.AddLast(request); } } } else { BasicStream os = new BasicStream(request.os.instance()); _connection.prepareBatchRequest(os); try { request.os.pos(0); os.writeBlob(request.os.readBlob(request.os.size())); } catch(Ice.LocalException) { _connection.abortBatchRequest(); throw; } _connection.finishBatchRequest(os, _compress); } LinkedListNode<Request> tmp = p; p = p.Next; _requests.Remove(tmp); } } catch(LocalExceptionWrapper ex) { _m.Lock(); try { Debug.Assert(_exception == null && _requests.Count > 0); _exception = ex.get(); _reference.getInstance().clientThreadPool().dispatch(delegate() { flushRequestsWithException(ex); }); } finally { _m.Unlock(); } } catch(Ice.LocalException ex) { _m.Lock(); try { Debug.Assert(_exception == null && _requests.Count > 0); _exception = ex; _reference.getInstance().clientThreadPool().dispatch(delegate() { flushRequestsWithException(ex); }); } finally { _m.Unlock(); } } if(sentCallbacks.Count > 0) { Instance instance = _reference.getInstance(); instance.clientThreadPool().dispatch(delegate() { foreach(Request r in sentCallbacks) { if(r.@out != null) { [email protected]__(r.sentCallback); } else if(r.batchOut != null) { r.batchOut.sent__(r.sentCallback); } } }); } // // 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(_updateRequestHandler && _exception == null) { _proxy.setRequestHandler__(_delegate, new ConnectionRequestHandler(_reference, _connection, _compress)); } _m.Lock(); try { Debug.Assert(!_initialized); if(_exception == null) { _initialized = true; _flushing = false; } _proxy = null; // Break cyclic reference count. _delegate = null; // Break cyclic reference count. _m.NotifyAll(); } finally { _m.Unlock(); } }
public void setException(Ice.LocalException ex) { _m.Lock(); try { Debug.Assert(!_initialized && _exception == null); Debug.Assert(_updateRequestHandler || _requests.Count == 0); _exception = ex; _proxy = null; // Break cyclic reference count. _delegate = 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. // if(_requests.Count > 0) { _reference.getInstance().clientThreadPool().dispatch(delegate() { flushRequestsWithException(ex); }); } _m.NotifyAll(); } finally { _m.Unlock(); } }