示例#1
0
        internal void Complete(Exception exc)
        {
            if (forward != null)
            {
                forward.Complete(exc);
                return;
            }
            exception = exc;
            if (InGet && (exc is ObjectDisposedException))
            {
                exception = new HttpListenerException(500, "Listener closed");
            }
            lock (locker)
            {
                completed = true;
                if (handle != null)
                {
                    handle.Set();
                }

                if (cb != null)
                {
                    ThreadPool.UnsafeQueueUserWorkItem(InvokeCB, this);
                }
            }
        }
        internal void Complete(Exception exc)
        {
            if (_forward != null)
            {
                _forward.Complete(exc);
                return;
            }
            _exception = exc;
            if (_inGet && (exc is ObjectDisposedException))
            {
                _exception = new HttpListenerException((int)HttpStatusCode.InternalServerError, SR.net_listener_close);
            }
            lock (_locker)
            {
                _completed = true;
                if (_handle != null)
                {
                    _handle.Set();
                }

                if (_cb != null)
                {
                    ThreadPool.UnsafeQueueUserWorkItem(s_invokeCB, this);
                }
            }
        }
示例#3
0
        public IAsyncResult BeginGetContext(AsyncCallback callback, Object state)
        {
            CheckDisposed();
            if (!listening)
            {
                throw new InvalidOperationException("Please, call Start before using this method.");
            }

            ListenerAsyncResult ares = new ListenerAsyncResult(callback, state);

            // lock wait_queue early to avoid race conditions
            lock (wait_queue) {
                lock (ctx_queue) {
                    HttpListenerContext ctx = GetContextFromQueue();
                    if (ctx != null)
                    {
                        ares.Complete(ctx, true);
                        return(ares);
                    }
                }

                wait_queue.Add(ares);
            }

            return(ares);
        }
示例#4
0
        public IAsyncResult BeginGetContext(AsyncCallback callback, Object state)
        {
            CheckDisposed();
            if (_state != State.Started)
            {
                throw new InvalidOperationException(SR.Format(SR.net_listener_mustcall, "Start()"));
            }

            ListenerAsyncResult ares = new ListenerAsyncResult(callback, state);

            // lock wait_queue early to avoid race conditions
            lock ((_asyncWaitQueue as ICollection).SyncRoot)
            {
                lock ((_contextQueue as ICollection).SyncRoot)
                {
                    HttpListenerContext ctx = GetContextFromQueue();
                    if (ctx != null)
                    {
                        ares.Complete(ctx, true);
                        return(ares);
                    }
                }

                _asyncWaitQueue.Add(ares);
            }

            return(ares);
        }
示例#5
0
        internal void RegisterContext(HttpListenerContext context)
        {
            lock ((_listenerContexts as ICollection).SyncRoot)
            {
                _listenerContexts[context] = context;
            }

            ListenerAsyncResult ares = null;

            lock ((_asyncWaitQueue as ICollection).SyncRoot)
            {
                if (_asyncWaitQueue.Count == 0)
                {
                    lock ((_contextQueue as ICollection).SyncRoot)
                        _contextQueue.Add(context);
                }
                else
                {
                    ares = _asyncWaitQueue[0];
                    _asyncWaitQueue.RemoveAt(0);
                }
            }

            if (ares != null)
            {
                ares.Complete(context);
            }
        }
 internal void RegisterContext(HttpListenerContext context)
 {
     try
     {
         Monitor.Enter(this.registry);
         this.registry[context] = context;
         Monitor.Enter(this.wait_queue);
         Monitor.Enter(this.ctx_queue);
         if (this.wait_queue.Count == 0)
         {
             this.ctx_queue.Add(context);
         }
         else
         {
             ListenerAsyncResult listenerAsyncResult = (ListenerAsyncResult)this.wait_queue[0];
             this.wait_queue.RemoveAt(0);
             listenerAsyncResult.Complete(context);
         }
     }
     finally
     {
         Monitor.Exit(this.ctx_queue);
         Monitor.Exit(this.wait_queue);
         Monitor.Exit(this.registry);
     }
 }
        /// <summary>Begins asynchronously retrieving an incoming request.</summary>
        /// <returns>An <see cref="T:System.IAsyncResult" /> object that indicates the status of the asynchronous operation.</returns>
        /// <param name="callback">An <see cref="T:System.AsyncCallback" /> delegate that references the method to invoke when a client request is available.</param>
        /// <param name="state">A user-defined object that contains information about the operation. This object is passed to the <paramref name="callback" /> delegate when the operation completes.</param>
        /// <exception cref="T:System.Net.HttpListenerException">A Win32 function call failed. Check the exception's <see cref="P:System.Net.HttpListenerException.ErrorCode" /> property to determine the cause of the exception.</exception>
        /// <exception cref="T:System.InvalidOperationException">This object has not been started or is currently stopped.</exception>
        /// <exception cref="T:System.ObjectDisposedException">This object is closed.</exception>
        public IAsyncResult BeginGetContext(AsyncCallback callback, object state)
        {
            this.CheckDisposed();
            if (!this.listening)
            {
                throw new InvalidOperationException("Please, call Start before using this method.");
            }
            ListenerAsyncResult listenerAsyncResult = new ListenerAsyncResult(callback, state);
            ArrayList           obj = this.wait_queue;

            lock (obj)
            {
                ArrayList obj2 = this.ctx_queue;
                lock (obj2)
                {
                    HttpListenerContext contextFromQueue = this.GetContextFromQueue();
                    if (contextFromQueue != null)
                    {
                        listenerAsyncResult.Complete(contextFromQueue, true);
                        return(listenerAsyncResult);
                    }
                }
                this.wait_queue.Add(listenerAsyncResult);
            }
            return(listenerAsyncResult);
        }
        internal void RegisterContext(HttpListenerContext context)
        {
            lock (registry)
                registry [context] = context;

            ListenerAsyncResult ares = null;

            lock (wait_queue)
            {
                if (wait_queue.Count == 0)
                {
                    lock (ctx_queue)
                        ctx_queue.Add(context);
                }
                else
                {
                    ares = (ListenerAsyncResult)wait_queue [0];
                    wait_queue.RemoveAt(0);
                }
            }
            if (ares != null)
            {
                ares.Complete(context);
            }
        }
示例#9
0
 internal void Complete(string error)
 {
     if (forward != null)
     {
         forward.Complete(error);
         return;
     }
     exception = new HttpListenerException(0, error);
     lock (locker)
     {
         completed = true;
         if (handle != null)
         {
             handle.Set();
         }
         if (cb != null)
         {
             ThreadPool.QueueUserWorkItem(InvokeCallback, this);
         }
     }
 }
示例#10
0
        internal void Complete(Exception exc)
        {
            if (_forward != null)
            {
                _forward.Complete(exc);
                return;
            }
            _exception = exc;
            if (InGet && (exc is ObjectDisposedException))
            {
                _exception = new HttpListenerException(500, "Listener closed");
            }
            lock (_locker)
            {
                _completed = true;
                _handle?.Set();

                if (_cb != null)
                {
                    ThreadPool.QueueUserWorkItem(_invokeCb, this);
                }
            }
        }
示例#11
0
        internal void RegisterContext(HttpListenerContext context)
        {
            lock (_registry)
                _registry[context] = context;

            ListenerAsyncResult ares = null;

            lock (_waitQueue)
            {
                if (_waitQueue.Count == 0)
                {
                    lock (_ctxQueue)
                        _ctxQueue.Add(context);
                }
                else
                {
                    ares = (ListenerAsyncResult)_waitQueue[0];
                    _waitQueue.RemoveAt(0);
                }
            }
            ares?.Complete(context);
        }
示例#12
0
 internal void RegisterContext(HttpListenerContext context)
 {
     try {
         Monitor.Enter(registry);
         registry [context] = context;
         Monitor.Enter(wait_queue);
         Monitor.Enter(ctx_queue);
         if (wait_queue.Count == 0)
         {
             ctx_queue.Add(context);
         }
         else
         {
             ListenerAsyncResult ares = (ListenerAsyncResult)wait_queue [0];
             wait_queue.RemoveAt(0);
             ares.Complete(context);
         }
     } finally {
         Monitor.Exit(ctx_queue);
         Monitor.Exit(wait_queue);
         Monitor.Exit(registry);
     }
 }
示例#13
0
        private void Cleanup(bool close_existing)
        {
            Hashtable obj = this.registry;

            lock (obj)
            {
                if (close_existing)
                {
                    foreach (object obj2 in this.registry.Keys)
                    {
                        HttpListenerContext httpListenerContext = (HttpListenerContext)obj2;
                        httpListenerContext.Connection.Close();
                    }
                    this.registry.Clear();
                }
                ArrayList obj3 = this.ctx_queue;
                lock (obj3)
                {
                    foreach (object obj4 in this.ctx_queue)
                    {
                        HttpListenerContext httpListenerContext2 = (HttpListenerContext)obj4;
                        httpListenerContext2.Connection.Close();
                    }
                    this.ctx_queue.Clear();
                }
                ArrayList obj5 = this.wait_queue;
                lock (obj5)
                {
                    foreach (object obj6 in this.wait_queue)
                    {
                        ListenerAsyncResult listenerAsyncResult = (ListenerAsyncResult)obj6;
                        listenerAsyncResult.Complete("Listener was closed.");
                    }
                    this.wait_queue.Clear();
                }
            }
        }
示例#14
0
		public IAsyncResult BeginGetContext (AsyncCallback callback, Object state)
		{
			CheckDisposed ();
			if (!listening)
				throw new InvalidOperationException ("Please, call Start before using this method.");

			ListenerAsyncResult ares = new ListenerAsyncResult (callback, state);

			// lock wait_queue early to avoid race conditions
			lock (wait_queue) {
				lock (ctx_queue) {
					HttpListenerContext ctx = GetContextFromQueue ();
					if (ctx != null) {
						ares.Complete (ctx, true);
						return ares;
					}
				}

				wait_queue.Add (ares);
			}

			return ares;
		}
        BeginGetRequest(
            AsyncCallback requestCallback,
            Object stateObject)
        {
            //
            // Validation
            //

            if (m_AppPoolHandle == NativeMethods.INVALID_HANDLE_VALUE)
            {
                throw new InvalidOperationException("The AppPool handle is invalid");
            }

            //
            // prepare the ListenerAsyncResult object ( this will have it's own
            // event that the user can wait on for IO completion - which means we
            // need to signal it when IO completes )
            //

            GlobalLog.Print("BeginGetRequest() creating ListenerAsyncResult");

            ListenerAsyncResult AResult = new ListenerAsyncResult(
                stateObject,
                requestCallback);

            AutoResetEvent m_Event = new AutoResetEvent(false);

            Marshal.WriteIntPtr(
                AResult.m_Overlapped,
                Win32.OverlappedhEventOffset,
                m_Event.Handle);

            //
            // issue unmanaged call until we read enough data:
            // usually starting with a InitialBufferSize==4096 bytes we should be
            // able to get all the headers ( and part of the entity body, if any
            // is present ), if we don't, if the call didn't fail for othe reasons,
            // we get indication in BytesReturned, on how big the buffer should be
            // to receive the data available, so usually the second call will
            // succeed, but we have to consider the case of two competing calls
            // for the same RequestId, and that's why we need a loop and not just
            // a try/retry-expecting-success fashion
            //

            int result;

            for (;;)
            {
                //
                // check if we're in a healthy state
                //
                if (AResult.m_Retries++ > m_MaxRetries)
                {
                    throw new InvalidOperationException("UlReceiveHttpRequest() Too many retries");
                }

                result =
                    ComNetOS.IsWinNt ?

                    UlSysApi.UlReceiveHttpRequest(
                        m_AppPoolHandle,
                        AResult.m_RequestId,
                        UlConstants.UL_RECEIVE_REQUEST_FLAG_COPY_BODY,
                        AResult.m_Buffer,
                        AResult.m_BufferSize,
                        ref AResult.m_BytesReturned,
                        AResult.m_Overlapped)

                :

                    UlVxdApi.UlReceiveHttpRequestHeaders(
                        m_AppPoolHandle,
                        AResult.m_RequestId,
                        0,
                        AResult.m_Buffer,
                        AResult.m_BufferSize,
                        ref AResult.m_BytesReturned,
                        AResult.m_Overlapped);

                GlobalLog.Print("UlReceiveHttpRequest() returns:"
                                + Convert.ToString(result));

                if (result == NativeMethods.ERROR_SUCCESS || result == NativeMethods.ERROR_IO_PENDING)
                {
                    //
                    // synchronous success or successfull pending: we are done
                    //

                    break;
                }

                if (result == NativeMethods.ERROR_INVALID_PARAMETER)
                {
                    //
                    // we might get this if somebody stole our RequestId,
                    // set RequestId to null
                    //

                    AResult.m_RequestId = 0;

                    //
                    // and start all over again with the buffer we
                    // just allocated
                    //

                    continue;
                }

                if (result == NativeMethods.ERROR_MORE_DATA)
                {
                    //
                    // the buffer was not big enough to fit the headers, we need
                    // to read the RequestId returned, grow the buffer, keeping
                    // the data already transferred
                    //

                    AResult.m_RequestId = Marshal.ReadInt64(IntPtrHelper.Add(AResult.m_Buffer, m_RequestIdOffset));

                    //
                    // allocate a new buffer of the required size
                    //

                    IntPtr NewBuffer = Marshal.AllocHGlobal(AResult.m_BytesReturned);

                    //
                    // copy the data already read from the old buffer into the
                    // new one
                    //

                    NativeMethods.CopyMemory(NewBuffer, AResult.m_Buffer, AResult.m_BufferSize);


                    //
                    // free the old buffer
                    //

                    Marshal.FreeHGlobal(AResult.m_Buffer);

                    //
                    // update buffer pointer and size
                    //

                    AResult.m_Buffer        = NewBuffer;
                    AResult.m_BufferSize    = AResult.m_BytesReturned;
                    AResult.m_BytesReturned = 0;

                    //
                    // and start all over again with the new buffer
                    //

                    continue;
                }

                //
                // someother bad error, possible( ? ) return values are:
                //
                // ERROR_INVALID_HANDLE
                // ERROR_INSUFFICIENT_BUFFER
                // ERROR_OPERATION_ABORTED
                // ERROR_IO_PENDING
                //

                throw new InvalidOperationException("UlReceiveHttpRequest() failed, err#" + Convert.ToString(result));
            }

            //
            // we get here only if a break happens, i.e.
            // 1) syncronous completion
            // 2) the IO pended
            //

            if (result == NativeMethods.ERROR_SUCCESS)
            {
                //
                // set syncronous completion to true
                //

                AResult.Complete(true);

                //
                // and call the internal callback
                //

                WaitCallback(AResult, false);
            }
            else
            {
                //
                // create a new delegate
                // and spin a new thread from the thread pool to wake up when the
                // event is signaled and call the delegate
                //

                ThreadPool.RegisterWaitForSingleObject(
                    m_Event,
                    new WaitOrTimerCallback(WaitCallback),
                    AResult,
                    -1,
                    true);
            }

            GlobalLog.Print("returning AResult");

            return(AResult);
        } // StartListen()