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