internal void Drain() { this._draining = true; if (this._timer != null) { this._timer.Dispose(); this._timer = null; } while (this._workItemCount > 0) { Thread.Sleep(100); } if (this._count == 0) { return; } while (true) { HttpWorkerRequest wr = this.DequeueRequest(false); if (wr == null) { return; } HttpRuntime.RejectRequestNow(wr, false); } }
// method called from HttpRuntime for incoming requests internal HttpWorkerRequest GetRequestToExecute(HttpWorkerRequest wr) { int workerThreads, ioThreads; ThreadPool.GetAvailableThreads(out workerThreads, out ioThreads); int freeThreads; if (_iis6) { freeThreads = workerThreads; // ignore IO threads to avoid starvation from Indigo TCP requests } else { freeThreads = (ioThreads > workerThreads) ? workerThreads : ioThreads; } // fast path when there are threads available and nothing queued if (freeThreads >= _minExternFreeThreads && _count == 0) { return(wr); } bool isLocal = IsLocal(wr); // fast path when there are threads for local requests available and nothing queued if (isLocal && freeThreads >= _minLocalFreeThreads && _count == 0) { return(wr); } // reject if queue limit exceeded if (_count >= _queueLimit) { HttpRuntime.RejectRequestNow(wr, false); return(null); } // can't execute the current request on the current thread -- need to queue QueueRequest(wr, isLocal); // maybe can execute a request previously queued if (freeThreads >= _minExternFreeThreads) { wr = DequeueRequest(false); // enough threads to process even external requests } else if (freeThreads >= _minLocalFreeThreads) { wr = DequeueRequest(true); // enough threads to process only local requests } else { wr = null; // not enough threads -> do nothing on this thread ScheduleMoreWorkIfNeeded(); // try to schedule to worker thread } return(wr); }
private HttpWorkerRequest DequeueRequest(bool localOnly) { HttpWorkerRequest wr = null; while (_count > 0) { lock (this) { if (_localQueue.Count > 0) { wr = (HttpWorkerRequest)_localQueue.Dequeue(); _count--; } else if (!localOnly && _externQueue.Count > 0) { wr = (HttpWorkerRequest)_externQueue.Dequeue(); _count--; } } if (wr == null) { break; } else { PerfCounters.DecrementGlobalCounter(GlobalPerfCounter.REQUESTS_QUEUED); PerfCounters.DecrementCounter(AppPerfCounter.REQUESTS_IN_APPLICATION_QUEUE); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Information, EtwTraceFlags.Infrastructure)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_REQ_DEQUEUED, wr); } if (!CheckClientConnected(wr)) { HttpRuntime.RejectRequestNow(wr, true); wr = null; PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.REQUESTS_DISCONNECTED); PerfCounters.IncrementCounter(AppPerfCounter.APP_REQUEST_DISCONNECTED); } else { break; } } } return(wr); }
internal HttpWorkerRequest GetRequestToExecute(HttpWorkerRequest wr) { int num; int num2; int num3; ThreadPool.GetAvailableThreads(out num, out num2); if (this._iis6) { num3 = num; } else { num3 = (num2 > num) ? num : num2; } if ((num3 < this._minExternFreeThreads) || (this._count != 0)) { bool isLocal = IsLocal(wr); if ((isLocal && (num3 >= this._minLocalFreeThreads)) && (this._count == 0)) { return(wr); } if (this._count >= this._queueLimit) { HttpRuntime.RejectRequestNow(wr, false); return(null); } this.QueueRequest(wr, isLocal); if (num3 >= this._minExternFreeThreads) { wr = this.DequeueRequest(false); return(wr); } if (num3 >= this._minLocalFreeThreads) { wr = this.DequeueRequest(true); return(wr); } wr = null; this.ScheduleMoreWorkIfNeeded(); } return(wr); }
private HttpWorkerRequest DequeueRequest(bool localOnly) { HttpWorkerRequest workerRequest = null; while (this._count > 0) { lock (this) { if (this._localQueue.Count > 0) { workerRequest = (HttpWorkerRequest)this._localQueue.Dequeue(); this._count--; } else if (!localOnly && (this._externQueue.Count > 0)) { workerRequest = (HttpWorkerRequest)this._externQueue.Dequeue(); this._count--; } } if (workerRequest == null) { return(workerRequest); } PerfCounters.DecrementGlobalCounter(GlobalPerfCounter.REQUESTS_QUEUED); PerfCounters.DecrementCounter(AppPerfCounter.REQUESTS_IN_APPLICATION_QUEUE); if (EtwTrace.IsTraceEnabled(4, 1)) { EtwTrace.Trace(EtwTraceType.ETW_TYPE_REQ_DEQUEUED, workerRequest); } if (this.CheckClientConnected(workerRequest)) { return(workerRequest); } HttpRuntime.RejectRequestNow(workerRequest, true); workerRequest = null; PerfCounters.IncrementGlobalCounter(GlobalPerfCounter.REQUESTS_DISCONNECTED); PerfCounters.IncrementCounter(AppPerfCounter.APP_REQUEST_DISCONNECTED); } return(workerRequest); }
// reject all requests internal void Drain() { // set flag before killing timer to shorten the code path // in the callback after the timer is disposed _draining = true; // stop the timer if (_timer != null) { ((IDisposable)_timer).Dispose(); _timer = null; } // wait for all work items to finish while (_workItemCount > 0) { Thread.Sleep(100); } // is queue empty? if (_count == 0) { return; } // reject the remaining requests for (;;) { HttpWorkerRequest wr = DequeueRequest(false); if (wr == null) { break; } HttpRuntime.RejectRequestNow(wr, false); } }