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.QueueUserWorkItem(InvokeCB, this); } } }
/// <summary> /// Begins getting an incoming request information asynchronously. /// </summary> /// <remarks> /// This asynchronous operation must be completed by calling the <see cref="EndGetContext"/> method. /// Typically, the method is invoked by the <paramref name="callback"/> delegate. /// </remarks> /// <returns> /// An <see cref="IAsyncResult"/> that contains the status of the asynchronous operation. /// </returns> /// <param name="callback"> /// An <see cref="AsyncCallback"/> delegate that references the method(s) /// called when the asynchronous operation completes. /// </param> /// <param name="state"> /// An <see cref="object"/> that contains a user defined object to pass to the <paramref name="callback"/> delegate. /// </param> /// <exception cref="ObjectDisposedException"> /// This object has been closed. /// </exception> /// <exception cref="InvalidOperationException"> /// The <see cref="HttpListener"/> has not been started or is stopped currently. /// </exception> 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 (((ICollection)wait_queue).SyncRoot) { lock (((ICollection)ctx_queue).SyncRoot) { HttpListenerContext ctx = GetContextFromQueue(); if (ctx != null) { ares.Complete(ctx, true); return(ares); } } wait_queue.Add(ares); } return(ares); }
internal void RegisterContext(HttpListenerContext context) { lock (((ICollection)registry).SyncRoot) registry [context] = context; ListenerAsyncResult ares = null; lock (((ICollection)wait_queue).SyncRoot) { if (wait_queue.Count == 0) { lock (((ICollection)ctx_queue).SyncRoot) ctx_queue.Add(context); } else { ares = wait_queue [0]; wait_queue.RemoveAt(0); } } if (ares != null) { ares.Complete(context); } }