コード例 #1
0
 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);
     }
 }
コード例 #2
0
        // 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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        // 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);
            }
        }