RequestTimeoutManager.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / xsp / System / Web / RequestTimeoutManager.cs / 1 / RequestTimeoutManager.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 * Request timeout manager -- implements the request timeout mechanism 
 */
namespace System.Web { 
    using System.Threading;
    using System.Collections;
    using System.Web.Util;
 
    internal class RequestTimeoutManager {
        private int                 _requestCount; 
        private DoubleLinkList[]    _lists;           // partitioned to avoid contention 
        private int                 _currentList;
        private int                 _inProgressLock;  // only 1 thread can be cancelling 
        private readonly TimeSpan   _timerPeriod = new TimeSpan(0, 0, 15); // 15 second init precision
        private Timer               _timer;

        internal RequestTimeoutManager() { 
            // initialize request lists
 
            _requestCount = 0; 

            _lists = new DoubleLinkList[13]; 
            for (int i = 0; i < _lists.Length; i++)
                _lists[i] = new DoubleLinkList();
            _currentList = 0;
 
            // init lock
 
            _inProgressLock = 0; 

            // create the timer 

#if DBG
            if (!Debug.IsTagPresent("Timer") || Debug.IsTagEnabled("Timer"))
#endif 
            {
                _timer = new Timer(new TimerCallback(this.TimerCompletionCallback), null, _timerPeriod, _timerPeriod); 
            } 

        } 

        internal void Stop() {
            // stop the timer
 
            if (_timer != null) {
                ((IDisposable)_timer).Dispose(); 
                _timer = null; 
            }
 
            while (_inProgressLock != 0)
                Thread.Sleep(100);

            // cancel all cancelable requests 

            if (_requestCount > 0) 
                CancelTimedOutRequests(DateTime.UtcNow.AddYears(1)); // future date 
        }
 
        private void TimerCompletionCallback(Object state) {
            if (_requestCount > 0)
                CancelTimedOutRequests(DateTime.UtcNow);
        } 

        private void CancelTimedOutRequests(DateTime now) { 
 
            // only one thread can be doing it
 
            if (Interlocked.CompareExchange(ref _inProgressLock, 1, 0) != 0)
                return;

            // collect them all into a separate list with minimal locking 

            ArrayList entries = new ArrayList(_requestCount); // size can change 
            DoubleLinkListEnumerator en; 

            for (int i = 0; i < _lists.Length; i++) { 
                lock (_lists[i]) {
                    en = _lists[i].GetEnumerator();

                    while (en.MoveNext()) 
                        entries.Add(en.GetDoubleLink());
 
                    en = null; 
                }
            } 

            // walk through the collected list to timeout what's needed

            int n = entries.Count; 

            for (int i = 0; i < n; i++) 
                ((RequestTimeoutEntry)entries[i]).TimeoutIfNeeded(now); 

            // this thread is done -- unlock 

            Interlocked.Exchange(ref _inProgressLock, 0);
        }
 
        internal void Add(HttpContext context) {
            if (context.TimeoutLink != null) { 
                ((RequestTimeoutEntry)context.TimeoutLink).IncrementCount(); 
                return;
            } 

            // create new entry

            RequestTimeoutEntry entry = new RequestTimeoutEntry(context); 

            // add it to the list 
 
            int i = _currentList++;
            if (i >= _lists.Length) { 
                i = 0;
                _currentList = 0;
            }
 
            entry.AddToList(_lists[i]);
            Interlocked.Increment(ref _requestCount); 
 
            // update HttpContext
            context.TimeoutLink = entry; 
        }

        internal void Remove(HttpContext context) {
            RequestTimeoutEntry entry = (RequestTimeoutEntry)context.TimeoutLink; 

            // remove from the list 
            if (entry != null) { 
                if( entry.DecrementCount() == 0 ) {
                    entry.RemoveFromList(); 
                    Interlocked.Decrement(ref _requestCount);
                } else {
                    return;
                } 
            }
 
            // update HttpContext 
            context.TimeoutLink = null;
        } 

        private class RequestTimeoutEntry : DoubleLink {
            private  HttpContext    _context;   // the request
            private  DoubleLinkList _list; 
            private int _count;
 
            internal RequestTimeoutEntry(HttpContext context) { 
                _context = context;
                _count = 1; 
            }

            internal void AddToList(DoubleLinkList list) {
                lock(list) { 
                    list.InsertTail(this);
                    _list = list; 
                } 
            }
 
            internal void RemoveFromList() {
                if (_list != null) {
                    lock(_list) {
                        Remove(); 
                        _list = null;
                    } 
                } 
            }
 
            internal void TimeoutIfNeeded(DateTime now) {
                Thread thread = _context.MustTimeout(now);
                if (thread != null) {
                    RemoveFromList(); 
                    thread.Abort(new HttpApplication.CancelModuleException(true));
                } 
            } 

            internal void IncrementCount() { 
                Interlocked.Increment( ref _count );
            }

            internal int DecrementCount() { 
                return Interlocked.Decrement( ref _count );
            } 
        } 
    }
 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 * Request timeout manager -- implements the request timeout mechanism 
 */
namespace System.Web { 
    using System.Threading;
    using System.Collections;
    using System.Web.Util;
 
    internal class RequestTimeoutManager {
        private int                 _requestCount; 
        private DoubleLinkList[]    _lists;           // partitioned to avoid contention 
        private int                 _currentList;
        private int                 _inProgressLock;  // only 1 thread can be cancelling 
        private readonly TimeSpan   _timerPeriod = new TimeSpan(0, 0, 15); // 15 second init precision
        private Timer               _timer;

        internal RequestTimeoutManager() { 
            // initialize request lists
 
            _requestCount = 0; 

            _lists = new DoubleLinkList[13]; 
            for (int i = 0; i < _lists.Length; i++)
                _lists[i] = new DoubleLinkList();
            _currentList = 0;
 
            // init lock
 
            _inProgressLock = 0; 

            // create the timer 

#if DBG
            if (!Debug.IsTagPresent("Timer") || Debug.IsTagEnabled("Timer"))
#endif 
            {
                _timer = new Timer(new TimerCallback(this.TimerCompletionCallback), null, _timerPeriod, _timerPeriod); 
            } 

        } 

        internal void Stop() {
            // stop the timer
 
            if (_timer != null) {
                ((IDisposable)_timer).Dispose(); 
                _timer = null; 
            }
 
            while (_inProgressLock != 0)
                Thread.Sleep(100);

            // cancel all cancelable requests 

            if (_requestCount > 0) 
                CancelTimedOutRequests(DateTime.UtcNow.AddYears(1)); // future date 
        }
 
        private void TimerCompletionCallback(Object state) {
            if (_requestCount > 0)
                CancelTimedOutRequests(DateTime.UtcNow);
        } 

        private void CancelTimedOutRequests(DateTime now) { 
 
            // only one thread can be doing it
 
            if (Interlocked.CompareExchange(ref _inProgressLock, 1, 0) != 0)
                return;

            // collect them all into a separate list with minimal locking 

            ArrayList entries = new ArrayList(_requestCount); // size can change 
            DoubleLinkListEnumerator en; 

            for (int i = 0; i < _lists.Length; i++) { 
                lock (_lists[i]) {
                    en = _lists[i].GetEnumerator();

                    while (en.MoveNext()) 
                        entries.Add(en.GetDoubleLink());
 
                    en = null; 
                }
            } 

            // walk through the collected list to timeout what's needed

            int n = entries.Count; 

            for (int i = 0; i < n; i++) 
                ((RequestTimeoutEntry)entries[i]).TimeoutIfNeeded(now); 

            // this thread is done -- unlock 

            Interlocked.Exchange(ref _inProgressLock, 0);
        }
 
        internal void Add(HttpContext context) {
            if (context.TimeoutLink != null) { 
                ((RequestTimeoutEntry)context.TimeoutLink).IncrementCount(); 
                return;
            } 

            // create new entry

            RequestTimeoutEntry entry = new RequestTimeoutEntry(context); 

            // add it to the list 
 
            int i = _currentList++;
            if (i >= _lists.Length) { 
                i = 0;
                _currentList = 0;
            }
 
            entry.AddToList(_lists[i]);
            Interlocked.Increment(ref _requestCount); 
 
            // update HttpContext
            context.TimeoutLink = entry; 
        }

        internal void Remove(HttpContext context) {
            RequestTimeoutEntry entry = (RequestTimeoutEntry)context.TimeoutLink; 

            // remove from the list 
            if (entry != null) { 
                if( entry.DecrementCount() == 0 ) {
                    entry.RemoveFromList(); 
                    Interlocked.Decrement(ref _requestCount);
                } else {
                    return;
                } 
            }
 
            // update HttpContext 
            context.TimeoutLink = null;
        } 

        private class RequestTimeoutEntry : DoubleLink {
            private  HttpContext    _context;   // the request
            private  DoubleLinkList _list; 
            private int _count;
 
            internal RequestTimeoutEntry(HttpContext context) { 
                _context = context;
                _count = 1; 
            }

            internal void AddToList(DoubleLinkList list) {
                lock(list) { 
                    list.InsertTail(this);
                    _list = list; 
                } 
            }
 
            internal void RemoveFromList() {
                if (_list != null) {
                    lock(_list) {
                        Remove(); 
                        _list = null;
                    } 
                } 
            }
 
            internal void TimeoutIfNeeded(DateTime now) {
                Thread thread = _context.MustTimeout(now);
                if (thread != null) {
                    RemoveFromList(); 
                    thread.Abort(new HttpApplication.CancelModuleException(true));
                } 
            } 

            internal void IncrementCount() { 
                Interlocked.Increment( ref _count );
            }

            internal int DecrementCount() { 
                return Interlocked.Decrement( ref _count );
            } 
        } 
    }
 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK