2 // System.Runtime.Remoting.Channels.RemotingThreadPool.cs
4 // Author: Lluis Sanchez Gual (lluis@ximian.com)
6 // 2005 (C) Copyright, Novell, Inc.
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.Collections
;
32 using System
.Threading
;
34 namespace System
.Runtime
.Remoting
.Channels
36 internal class RemotingThreadPool
38 const int ThreadLimit
= 1000;
39 const int ThreadWaitTime
= 20000; //ms
40 const int PoolGrowDelay
= 500; // ms
41 const int MinThreads
= 3;
45 Queue workItems
= new Queue ();
46 AutoResetEvent threadDone
= new AutoResetEvent (false);
47 ArrayList runningThreads
= new ArrayList ();
51 static object globalLock
= new object ();
52 static RemotingThreadPool sharedPool
;
54 public static RemotingThreadPool
GetSharedPool ()
57 if (sharedPool
== null)
58 sharedPool
= new RemotingThreadPool ();
59 sharedPool
.poolUsers
++;
74 foreach (Thread t
in runningThreads
)
76 runningThreads
.Clear ();
78 if (this == sharedPool
)
83 public bool RunThread (ThreadStart threadStart
)
87 throw new RemotingException ("Server channel stopped.");
89 if (freeThreads
> 0) {
91 workItems
.Enqueue (threadStart
);
92 Monitor
.Pulse (workItems
);
94 } else if (runningThreads
.Count
< MinThreads
) {
95 workItems
.Enqueue (threadStart
);
101 // Try again some ms later, and if there are still no free threads,
102 // then create a new one
104 threadDone
.WaitOne (PoolGrowDelay
, false);
108 throw new RemotingException ("Server channel stopped.");
110 if (freeThreads
> 0) {
112 workItems
.Enqueue (threadStart
);
113 Monitor
.Pulse (workItems
);
115 if (runningThreads
.Count
>= ThreadLimit
)
117 workItems
.Enqueue (threadStart
);
124 void StartPoolThread ()
126 Thread thread
= new Thread (new ThreadStart (PoolThread
));
127 runningThreads
.Add (thread
);
128 thread
.IsBackground
= true;
135 ThreadStart work
= null;
138 if (workItems
.Count
> 0)
139 work
= (ThreadStart
) workItems
.Dequeue ();
143 if (!Monitor
.Wait (workItems
, ThreadWaitTime
)) {
144 // Maybe it timed out when the work was being queued.
145 if (workItems
.Count
> 0) {
146 work
= (ThreadStart
) workItems
.Dequeue ();
149 if (freeThreads
== 0) threadDone
.Reset ();
150 runningThreads
.Remove (Thread
.CurrentThread
);
156 } while (work
== null);
163 Console
.WriteLine("The exception was caught during RemotingThreadPool.PoolThread - work: {0}, {1}", ex
.GetType(), ex
.Message
);