001: /*
002: * Distributed as part of c3p0 v.0.9.1.2
003: *
004: * Copyright (C) 2005 Machinery For Change, Inc.
005: *
006: * Author: Steve Waldman <swaldman@mchange.com>
007: *
008: * This library is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU Lesser General Public License version 2.1, as
010: * published by the Free Software Foundation.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this software; see the file LICENSE. If not, write to the
019: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package com.mchange.v2.resourcepool;
024:
025: import java.util.*;
026: import com.mchange.v2.async.*;
027:
028: public class BasicResourcePoolFactory extends ResourcePoolFactory {
029: public static BasicResourcePoolFactory createNoEventSupportInstance(
030: int num_task_threads) {
031: return createNoEventSupportInstance(null, null,
032: num_task_threads);
033: }
034:
035: public static BasicResourcePoolFactory createNoEventSupportInstance(
036: AsynchronousRunner taskRunner, Timer timer) {
037: return createNoEventSupportInstance(taskRunner, timer,
038: ResourcePoolFactory.DEFAULT_NUM_TASK_THREADS);
039: }
040:
041: private static BasicResourcePoolFactory createNoEventSupportInstance(
042: AsynchronousRunner taskRunner, Timer timer,
043: int default_num_task_threads) {
044: return new BasicResourcePoolFactory(taskRunner, timer,
045: default_num_task_threads, true);
046: }
047:
048: int start = -1; //default to min
049: int min = 1;
050: int max = 12;
051: int inc = 3;
052: int retry_attempts = -1; //by default, retry acquisitions forever
053: int retry_delay = 1000; //1 second
054: long idle_resource_test_period = -1; //milliseconds, by default we don't test idle resources
055: long max_age = -1; //milliseconds, by default resources never expire
056: long max_idle_time = -1; //milliseconds, by default resources never expire
057: long excess_max_idle_time = -1; //milliseconds, by default resources never expire
058: long destroy_overdue_resc_time = -1; //milliseconds
059: long expiration_enforcement_delay = -1; //automatic, we come up with a reasonable default based on time params
060:
061: boolean break_on_acquisition_failure = true;
062: boolean debug_store_checkout_stacktrace = false;
063:
064: AsynchronousRunner taskRunner;
065: boolean taskRunner_is_external;
066:
067: RunnableQueue asyncEventQueue;
068: boolean asyncEventQueue_is_external;
069:
070: Timer timer;
071: boolean timer_is_external;
072:
073: int default_num_task_threads;
074:
075: Set liveChildren;
076:
077: //OLD
078: // Set rqUsers = null;
079: // SimpleRunnableQueue rq = null;
080:
081: // Set timerUsers = null;
082: // Timer timer = null;
083: //END OLD
084:
085: BasicResourcePoolFactory() {
086: this (null, null, null);
087: }
088:
089: BasicResourcePoolFactory(AsynchronousRunner taskRunner,
090: RunnableQueue asyncEventQueue, Timer timer) {
091: this (taskRunner, asyncEventQueue, timer,
092: DEFAULT_NUM_TASK_THREADS);
093: }
094:
095: BasicResourcePoolFactory(int num_task_threads) {
096: this (null, null, null, num_task_threads);
097: }
098:
099: BasicResourcePoolFactory(AsynchronousRunner taskRunner,
100: Timer timer, int default_num_task_threads,
101: boolean no_event_support) {
102: this (taskRunner, null, timer, default_num_task_threads);
103: if (no_event_support)
104: asyncEventQueue_is_external = true; //if it's null, and external, it simply won't exist...
105: }
106:
107: BasicResourcePoolFactory(AsynchronousRunner taskRunner,
108: RunnableQueue asyncEventQueue, Timer timer,
109: int default_num_task_threads) {
110: this .taskRunner = taskRunner;
111: this .taskRunner_is_external = (taskRunner != null);
112:
113: this .asyncEventQueue = asyncEventQueue;
114: this .asyncEventQueue_is_external = (asyncEventQueue != null);
115:
116: this .timer = timer;
117: this .timer_is_external = (timer != null);
118:
119: this .default_num_task_threads = default_num_task_threads;
120: }
121:
122: private void createThreadResources() {
123: if (!taskRunner_is_external) {
124: //taskRunner = new RoundRobinAsynchronousRunner( default_num_task_threads, true );
125: taskRunner = new ThreadPoolAsynchronousRunner(
126: default_num_task_threads, true);
127: if (!asyncEventQueue_is_external)
128: asyncEventQueue = ((Queuable) taskRunner)
129: .asRunnableQueue();
130: }
131: if (!asyncEventQueue_is_external)
132: asyncEventQueue = new CarefulRunnableQueue(true, false);
133: if (!timer_is_external)
134: timer = new Timer(true);
135:
136: this .liveChildren = new HashSet();
137: }
138:
139: private void destroyThreadResources() {
140: if (!taskRunner_is_external) {
141: taskRunner.close();
142: taskRunner = null;
143: }
144: if (!asyncEventQueue_is_external) {
145: asyncEventQueue.close();
146: asyncEventQueue = null;
147: }
148: if (!timer_is_external) {
149: timer.cancel();
150: timer = null;
151: }
152:
153: this .liveChildren = null;
154: }
155:
156: // synchronized RunnableQueue getSharedRunnableQueue( BasicResourcePool pool )
157: // {
158: // if (rqUsers == null)
159: // {
160: // rqUsers = new HashSet();
161: // rq = new SimpleRunnableQueue(true);
162: // }
163: // rqUsers.add( pool );
164: // return rq;
165: // }
166:
167: // synchronized Timer getTimer( BasicResourcePool pool )
168: // {
169: // if (timerUsers == null)
170: // {
171: // timerUsers = new HashSet();
172: // timer = new Timer( true );
173: // }
174: // timerUsers.add( pool );
175: // return timer;
176: // }
177:
178: synchronized void markBroken(BasicResourcePool pool) {
179: //System.err.println("markBroken -- liveChildren: " + liveChildren);
180: if (liveChildren != null) //keep this method idempotent!
181: {
182: liveChildren.remove(pool);
183: if (liveChildren.isEmpty())
184: destroyThreadResources();
185: }
186: // rqUsers.remove( pool );
187: // if (rqUsers.size() == 0)
188: // {
189: // rqUsers = null;
190: // rq.close();
191: // rq = null;
192: // }
193:
194: // timerUsers.remove( pool );
195: // if (timerUsers.size() == 0)
196: // {
197: // timerUsers = null;
198: // timer.cancel();
199: // timer = null;
200: // }
201: }
202:
203: /**
204: * If start is less than min, it will
205: * be ignored, and the pool will start
206: * with min.
207: */
208: public synchronized void setStart(int start)
209: throws ResourcePoolException {
210: this .start = start;
211: }
212:
213: public synchronized int getStart() throws ResourcePoolException {
214: return start;
215: }
216:
217: public synchronized void setMin(int min)
218: throws ResourcePoolException {
219: this .min = min;
220: }
221:
222: public synchronized int getMin() throws ResourcePoolException {
223: return min;
224: }
225:
226: public synchronized void setMax(int max)
227: throws ResourcePoolException {
228: this .max = max;
229: }
230:
231: public synchronized int getMax() throws ResourcePoolException {
232: return max;
233: }
234:
235: public synchronized void setIncrement(int inc)
236: throws ResourcePoolException {
237: this .inc = inc;
238: }
239:
240: public synchronized int getIncrement() throws ResourcePoolException {
241: return inc;
242: }
243:
244: public synchronized void setAcquisitionRetryAttempts(
245: int retry_attempts) throws ResourcePoolException {
246: this .retry_attempts = retry_attempts;
247: }
248:
249: public synchronized int getAcquisitionRetryAttempts()
250: throws ResourcePoolException {
251: return retry_attempts;
252: }
253:
254: public synchronized void setAcquisitionRetryDelay(int retry_delay)
255: throws ResourcePoolException {
256: this .retry_delay = retry_delay;
257: }
258:
259: public synchronized int getAcquisitionRetryDelay()
260: throws ResourcePoolException {
261: return retry_delay;
262: }
263:
264: public synchronized void setIdleResourceTestPeriod(long test_period) {
265: this .idle_resource_test_period = test_period;
266: }
267:
268: public synchronized long getIdleResourceTestPeriod() {
269: return idle_resource_test_period;
270: }
271:
272: public synchronized void setResourceMaxAge(long max_age)
273: throws ResourcePoolException {
274: this .max_age = max_age;
275: }
276:
277: public synchronized long getResourceMaxAge()
278: throws ResourcePoolException {
279: return max_age;
280: }
281:
282: public synchronized void setResourceMaxIdleTime(long millis)
283: throws ResourcePoolException {
284: this .max_idle_time = millis;
285: }
286:
287: public synchronized long getResourceMaxIdleTime()
288: throws ResourcePoolException {
289: return max_idle_time;
290: }
291:
292: public synchronized void setExcessResourceMaxIdleTime(long millis)
293: throws ResourcePoolException {
294: this .excess_max_idle_time = millis;
295: }
296:
297: public synchronized long getExcessResourceMaxIdleTime()
298: throws ResourcePoolException {
299: return excess_max_idle_time;
300: }
301:
302: public synchronized long getDestroyOverdueResourceTime()
303: throws ResourcePoolException {
304: return destroy_overdue_resc_time;
305: }
306:
307: public synchronized void setDestroyOverdueResourceTime(long millis)
308: throws ResourcePoolException {
309: this .destroy_overdue_resc_time = millis;
310: }
311:
312: public synchronized void setExpirationEnforcementDelay(
313: long expiration_enforcement_delay)
314: throws ResourcePoolException {
315: this .expiration_enforcement_delay = expiration_enforcement_delay;
316: }
317:
318: public synchronized long getExpirationEnforcementDelay()
319: throws ResourcePoolException {
320: return expiration_enforcement_delay;
321: }
322:
323: public synchronized void setBreakOnAcquisitionFailure(
324: boolean break_on_acquisition_failure)
325: throws ResourcePoolException {
326: this .break_on_acquisition_failure = break_on_acquisition_failure;
327: }
328:
329: public synchronized boolean getBreakOnAcquisitionFailure()
330: throws ResourcePoolException {
331: return break_on_acquisition_failure;
332: }
333:
334: public synchronized void setDebugStoreCheckoutStackTrace(
335: boolean debug_store_checkout_stacktrace)
336: throws ResourcePoolException {
337: this .debug_store_checkout_stacktrace = debug_store_checkout_stacktrace;
338: }
339:
340: public synchronized boolean getDebugStoreCheckoutStackTrace()
341: throws ResourcePoolException {
342: return debug_store_checkout_stacktrace;
343: }
344:
345: public synchronized ResourcePool createPool(ResourcePool.Manager mgr)
346: throws ResourcePoolException {
347: if (liveChildren == null)
348: createThreadResources();
349: //System.err.println("Created liveChildren: " + liveChildren);
350: ResourcePool child = new BasicResourcePool(mgr, start, min,
351: max, inc, retry_attempts, retry_delay,
352: idle_resource_test_period, max_age, max_idle_time,
353: excess_max_idle_time, destroy_overdue_resc_time,
354: expiration_enforcement_delay,
355: break_on_acquisition_failure,
356: debug_store_checkout_stacktrace, taskRunner,
357: asyncEventQueue, timer, this);
358: liveChildren.add(child);
359: return child;
360: }
361: }
|