KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > poa > RPPoolManager


1 package org.jacorb.poa;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23 import org.apache.avalon.framework.configuration.*;
24 import org.apache.avalon.framework.logger.Logger;
25 import org.jacorb.poa.except.*;
26
27 import org.jacorb.poa.except.POAInternalError;
28 import java.util.*;
29
30 /**
31  * This class provides and manages a pool of ready started threads for
32  * request processing.
33  *
34  * @author Gerald Brose, Reimo Tiedemann, FU Berlin
35  * @version 1.04, 10/26/99, RT
36  * @see org.jacorb.poa.RequestProcessor
37  */

38
39 public class RPPoolManager
40 {
41     private RPPoolManagerListener pmListener;
42
43     // the current for (un)registering the invocation contexts
44
private Current current;
45     /**
46      * <code>pool</code> is the set of currently available (inactive) request processors
47      */

48     private Vector pool;
49     /**
50      * <code>activeProcessors</code> is the set of currently active processors
51      */

52     private Vector activeProcessors;
53     /**
54      * <code>unused_size</code> represents the current number of unused request processors
55      * in the pool.
56      */

57     private int unused_size;
58     /**
59      * <code>max_pool_size</code> is the maximum size of the pool.
60      */

61     private int max_pool_size;
62     /**
63      * <code>min_pool_size</code> is the minimum number of request processors.
64      */

65     private int min_pool_size;
66     // a flag for delay the pool initialization
67
private boolean inUse = false;
68
69     private Configuration configuration;
70     private Logger logger;
71
72     private RPPoolManager() {
73     }
74
75     protected RPPoolManager(Current _current, int min, int max,
76                             Logger _logger, Configuration _configuration)
77     {
78         current = _current;
79         max_pool_size = max;
80         min_pool_size = min;
81         logger = _logger;
82         configuration = _configuration;
83     }
84
85     private void addProcessor()
86     {
87         RequestProcessor rp = new RequestProcessor(this);
88         try
89         {
90             rp.configure(this.configuration);
91         } catch (ConfigurationException ex)
92         {
93             throw new RuntimeException JavaDoc (ex.toString());
94         }
95         current._addContext(rp, rp);
96         rp.setDaemon(true);
97         pool.addElement(rp);
98         unused_size++;
99         rp.start();
100     }
101
102     protected synchronized void addRPPoolManagerListener(RPPoolManagerListener listener)
103     {
104         pmListener = EventMulticaster.add(pmListener, listener);
105     }
106
107     protected synchronized void destroy()
108     {
109         if (pool == null || inUse == false) return;
110         
111         // wait until all active processors complete
112
while (!activeProcessors.isEmpty())
113         {
114             try
115             {
116                 wait();
117             }
118             catch (InterruptedException JavaDoc ex)
119             {
120                 // ignore
121
}
122         }
123         
124         RequestProcessor[] rps = new RequestProcessor[pool.size()];
125         pool.copyInto(rps);
126         for (int i=0; i<rps.length; i++)
127         {
128             if (rps[i].isActive())
129             {
130                 throw new POAInternalError("error: request processor is active (RequestProcessorPM.destroy)");
131
132             }
133             else
134             {
135                 pool.removeElement(rps[i]);
136                 unused_size--;
137                 current._removeContext(rps[i]);
138                 rps[i].end();
139             }
140         }
141         inUse = false;
142     }
143
144     /**
145      * returns the number of unused processors contained in the pool
146      */

147
148     protected int getPoolCount()
149     {
150         return (pool == null) ? 0 : pool.size();
151     }
152
153     /**
154      * returns the size of the processor pool (used and unused processors)
155      */

156
157     protected synchronized int getPoolSize()
158     {
159         return unused_size;
160     }
161
162     /**
163      * returns a processor from pool, the first call causes
164      * the initialization of the processor pool,
165      * if no processor available the number of processors
166      * will increased until the max_pool_size is reached,
167      * this method blocks if no processor available and the
168      * max_pool_size is reached until a processor will released
169      */

170
171     protected synchronized RequestProcessor getProcessor()
172     {
173         if (!inUse)
174         {
175             init();
176             inUse = true;
177         }
178
179         if (pool.size() == 0 && unused_size < max_pool_size)
180         {
181             addProcessor();
182         }
183
184         while (pool.size() == 0)
185         {
186             if (logger.isWarnEnabled())
187             {
188                 logger.warn("Thread pool exhausted, consider increasing "
189                           + "jacorb.poa.thread_pool_max (currently: "
190                           + max_pool_size + ")");
191             }
192             try
193             {
194                 wait();
195             }
196             catch (InterruptedException JavaDoc e)
197             {
198             }
199         }
200         RequestProcessor rp = (RequestProcessor) pool.remove( pool.size() - 1 );
201         activeProcessors.add (rp);
202         
203         // notify a pool manager listener
204
if (pmListener != null)
205             pmListener.processorRemovedFromPool(rp, pool.size(), unused_size);
206         return rp;
207     }
208
209     private void init()
210     {
211         pool = new Vector(max_pool_size);
212         activeProcessors = new Vector(max_pool_size);
213         for (int i = 0; i < min_pool_size; i++)
214         {
215             addProcessor();
216         }
217     }
218
219     /**
220      * gives a processor back into the pool if the number of
221      * available processors is smaller than min_pool_size,
222      * otherwise the processor will terminated
223      */

224
225     protected synchronized void releaseProcessor(RequestProcessor rp)
226     {
227         activeProcessors.remove (rp);
228         
229         if (pool.size() < min_pool_size)
230         {
231             pool.addElement(rp);
232         }
233         else
234         {
235             unused_size--;
236             current._removeContext(rp);
237             rp.end();
238         }
239         // notify a pool manager listener
240
if (pmListener != null)
241             pmListener.processorAddedToPool(rp, pool.size(), unused_size);
242
243         // notify whoever is waiting for the release of active processors
244
notifyAll();
245     }
246
247     protected synchronized void removeRPPoolManagerListener(RPPoolManagerListener listener)
248     {
249         pmListener = EventMulticaster.remove(pmListener, listener);
250     }
251 }
252
Popular Tags