001: /*
002: * This software is released under a licence similar to the Apache Software Licence.
003: * See org.logicalcobwebs.proxool.package.html for details.
004: * The latest version is available at http://proxool.sourceforge.net
005: */
006: package org.logicalcobwebs.proxool;
007:
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010:
011: import java.util.Iterator;
012:
013: /**
014: * Controls the {@link Prototyper prototypers}
015: * @version $Revision: 1.10 $, $Date: 2006/01/18 14:40:01 $
016: * @author bill
017: * @author $Author: billhorsman $ (current maintainer)
018: * @since Proxool 0.8
019: */
020: public class PrototyperController {
021:
022: private static final Log LOG = LogFactory
023: .getLog(PrototyperController.class);
024:
025: private static PrototyperThread prototyperThread;
026:
027: private static boolean keepSweeping;
028:
029: private static final String LOCK = "LOCK";
030:
031: private static void startPrototyper() {
032: if (prototyperThread == null) {
033: synchronized (LOCK) {
034: if (prototyperThread == null) {
035: prototyperThread = new PrototyperThread(
036: "Prototyper");
037: prototyperThread.start();
038: }
039: }
040: }
041: }
042:
043: /**
044: * Trigger prototyping immediately. Runs inside a new Thread so
045: * control returns as quick as possible. You should call this whenever
046: * you suspect that building more connections might be a good idea.
047: * @param alias
048: */
049: protected static void triggerSweep(String alias) {
050: try {
051: // Ensure that we're not in the process of shutting down the pool
052: ConnectionPool cp = ConnectionPoolManager.getInstance()
053: .getConnectionPool(alias);
054: try {
055: cp.acquirePrimaryReadLock();
056: cp.getPrototyper().triggerSweep();
057: } catch (InterruptedException e) {
058: LOG.error("Couldn't acquire primary read lock", e);
059: } finally {
060: cp.releasePrimaryReadLock();
061: }
062: } catch (ProxoolException e) {
063: if (LOG.isDebugEnabled()) {
064: LOG
065: .debug("Couldn't trigger prototyper triggerSweep for '"
066: + alias
067: + "' - maybe it's just been shutdown");
068: }
069: }
070: startPrototyper();
071: try {
072: // If we are currently sweeping this will cause it to loop through
073: // once more
074: keepSweeping = true;
075: // If we aren't already started then this will start a new sweep
076: if (prototyperThread != null) {
077: prototyperThread.doNotify();
078: }
079: } catch (IllegalMonitorStateException e) {
080: LOG.debug("Hmm", e);
081: if (Thread.activeCount() > 10 && LOG.isInfoEnabled()) {
082: LOG.info("Suspicious thread count of "
083: + Thread.activeCount());
084: }
085: } catch (IllegalThreadStateException e) {
086: // Totally expected. Should happen all the time. Just means that
087: // we are already sweeping.
088: if (LOG.isDebugEnabled()) {
089: LOG
090: .debug("Ignoring attempt to prototype whilst already prototyping");
091: }
092: }
093: }
094:
095: public static boolean isKeepSweeping() {
096: return keepSweeping;
097: }
098:
099: public static void sweepStarted() {
100: keepSweeping = false;
101: }
102:
103: /**
104: * Stop all house keeper threads
105: */
106: protected static void shutdown() {
107: synchronized (LOCK) {
108: if (prototyperThread != null) {
109: LOG.info("Stopping " + prototyperThread.getName()
110: + " thread");
111: prototyperThread.cancel();
112: prototyperThread = null;
113: }
114: }
115: }
116: }
117:
118: /*
119: Revision history:
120: $Log: PrototyperController.java,v $
121: Revision 1.10 2006/01/18 14:40:01 billhorsman
122: Unbundled Jakarta's Commons Logging.
123:
124: Revision 1.9 2004/04/05 22:54:57 billhorsman
125: Check if notify thread has been shutdown before triggering it.
126:
127: Revision 1.8 2004/03/26 15:58:56 billhorsman
128: Fixes to ensure that house keeper and prototyper threads finish after shutdown.
129:
130: Revision 1.7 2004/03/25 22:02:15 brenuart
131: First step towards pluggable ConnectionBuilderIF & ConnectionValidatorIF.
132: Include some minor refactoring that lead to deprecation of some PrototyperController methods.
133:
134: Revision 1.5 2003/03/10 23:43:11 billhorsman
135: reapplied checkstyle that i'd inadvertently let
136: IntelliJ change...
137:
138: Revision 1.4 2003/03/10 16:28:02 billhorsman
139: removed debug trace
140:
141: Revision 1.3 2003/03/10 15:26:47 billhorsman
142: refactoringn of concurrency stuff (and some import
143: optimisation)
144:
145: Revision 1.2 2003/03/06 12:43:32 billhorsman
146: removed paranoid debug
147:
148: Revision 1.1 2003/03/05 18:42:33 billhorsman
149: big refactor of prototyping and house keeping to
150: drastically reduce the number of threads when using
151: many pools
152:
153: */
|