Got rid of those Internal(1) warnings
[mono.git] / mcs / class / System.Web / System.Web / TimeoutManager.cs
1 //
2 // System.Web.TimeoutManager
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2003 Novell, Inc (http://www.novell.com)
8 //
9
10 using System;
11 using System.Collections;
12 using System.Threading;
13 using System.Web.Configuration;
14
15 namespace System.Web
16 {
17         class StepTimeout
18         {
19         }
20         
21         class TimeoutManager
22         {
23                 Timer timer;
24                 Hashtable contexts;
25
26                 public TimeoutManager ()
27                 {
28                         contexts = Hashtable.Synchronized (new Hashtable ());
29                         timer = new Timer (new TimerCallback (CheckTimeouts), null, 0, 15000);
30                 }
31
32                 public void Add (HttpContext context)
33                 {
34                         object value = contexts [context];
35                         if (value == null) {
36                                 value = Thread.CurrentThread;
37                         } else if (value is Thread) {
38                                 ArrayList list = new ArrayList ();
39                                 list.Add (value);
40                                 list.Add (Thread.CurrentThread);
41                                 value = list;
42                         } else {
43                                 ArrayList list = (ArrayList) value;
44                                 list.Add (Thread.CurrentThread);
45                                 value = list;
46                         }
47
48                         lock (this) {
49                                 contexts [context] = value;
50                         }
51                 }
52
53                 public Thread Remove (HttpContext context)
54                 {
55                         object value = contexts [context];
56                         if (value == null)
57                                 return null;
58
59                         if (value is Thread) {
60                                 lock (this) {
61                                         contexts.Remove (context);
62                                 }
63                                 return (Thread) value;
64                         }
65                         
66                         ArrayList list = (ArrayList) value;
67                         Thread result = null;
68                         if (list.Count > 0) {
69                                 result = (Thread) list [list.Count - 1];
70                                 list.RemoveAt (list.Count - 1);
71                         }
72
73                         if (list.Count == 0) {
74                                 lock (this) {
75                                         contexts.Remove (context);
76                                 }
77                         }
78
79                         return result;
80                 }
81
82                 void CheckTimeouts (object state)
83                 {
84                         if (contexts.Count == 0) {
85                                 return;
86                         }
87
88                         DateTime now = DateTime.Now;
89                         ArrayList clist = new ArrayList ();
90
91                         lock (this) { // The lock prevents Keys enumerator from being out of synch
92                                 clist.AddRange (contexts.Keys);
93                         }
94
95                         foreach (HttpContext context in clist) {
96                                 if (!context.CheckIfTimeout (now))
97                                         continue;
98
99                                 Thread thread = Remove (context);
100                                 if (thread != null) // Only if context is removed right after the lock
101                                         thread.Abort (new StepTimeout ());
102                         }
103                 }
104         }
105 }
106