// // Marshal the endpoint // public override void streamWrite(BasicStream s) { s.writeShort(_type); s.startWriteEncaps(_rawEncoding, Ice.FormatType.DefaultFormat); s.writeBlob(_rawBytes); s.endWriteEncaps(); }
public BatchRequestQueue(Instance instance, bool datagram) { Ice.InitializationData initData = instance.initializationData(); _interceptor = initData.batchRequestInterceptor; _batchStreamInUse = false; _batchRequestNum = 0; _batchStream = new BasicStream(instance, Ice.Util.currentProtocolEncoding); _batchStream.writeBlob(Protocol.requestBatchHdr); _batchMarker = _batchStream.size(); _request = new BatchRequestI(this); _maxSize = instance.batchAutoFlushSize(); if (_maxSize > 0 && datagram) { int udpSndSize = initData.properties.getPropertyAsIntWithDefault("Ice.UDP.SndSize", 65535 - _udpOverhead); if (udpSndSize < _maxSize) { _maxSize = udpSndSize; } } }
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(), Ice.Util.currentProtocolEncoding); _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(); } }