Beispiel #1
0
        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();
            }
        }