KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > resource > connectionmanager > IdleRemover


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.resource.connectionmanager;
23
24 import java.security.AccessController JavaDoc;
25 import java.security.PrivilegedAction JavaDoc;
26 import java.util.ArrayList JavaDoc;
27
28 import java.util.Collection JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import org.jboss.logging.Logger;
31
32 /**
33  * IdleRemover
34  *
35  * @author <a HREF="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
36  * @author <a HREF="mailto:adrian@jboss.com">Adrian Brock</a>
37  * @author <a HREF="mailto:weston.price@jboss.com>Weston Price</a>
38  * @version $Revision: 57101 $
39  */

40 public class IdleRemover
41 {
42    private final Logger log = Logger.getLogger(getClass());
43
44    private final Collection JavaDoc pools = new ArrayList JavaDoc();
45
46    private long interval = Long.MAX_VALUE;
47
48    private long next = Long.MAX_VALUE;//important initialization!
49

50    private static final IdleRemover remover = new IdleRemover();
51
52    public static void registerPool(IdleConnectionRemovalSupport mcp, long interval)
53    {
54       remover.internalRegisterPool(mcp, interval);
55    }
56
57    public static void unregisterPool(IdleConnectionRemovalSupport mcp)
58    {
59       remover.internalUnregisterPool(mcp);
60    }
61    
62    /**
63     * For testing
64     */

65    public static void waitForBackgroundThread()
66    {
67       synchronized (remover.pools)
68       {
69          return;
70       }
71    }
72    
73    private IdleRemover ()
74    {
75       AccessController.doPrivileged(new PrivilegedAction JavaDoc()
76       {
77          public Object JavaDoc run()
78          {
79             Runnable JavaDoc runnable = new IdleRemoverRunnable();
80             Thread JavaDoc removerThread = new Thread JavaDoc(runnable, "IdleRemover");
81             removerThread.setDaemon(true);
82             removerThread.start();
83             return null;
84          }
85       });
86    }
87    
88    private void internalRegisterPool(IdleConnectionRemovalSupport mcp, long interval)
89    {
90       log.debug("internalRegisterPool: registering pool with interval " + interval + " old interval: " + this.interval);
91       synchronized (pools)
92       {
93          pools.add(mcp);
94          if (interval > 1 && interval/2 < this.interval)
95          {
96             this.interval = interval/2;
97             long maybeNext = System.currentTimeMillis() + this.interval;
98             if (next > maybeNext && maybeNext > 0)
99             {
100                next = maybeNext;
101                log.debug("internalRegisterPool: about to notify thread: old next: " + next + ", new next: " + maybeNext);
102                pools.notify();
103             }
104          }
105       }
106    }
107
108    private void internalUnregisterPool(IdleConnectionRemovalSupport mcp)
109    {
110       synchronized (pools)
111       {
112          pools.remove(mcp);
113          if (pools.size() == 0)
114          {
115             log.debug("internalUnregisterPool: setting interval to Long.MAX_VALUE");
116             interval = Long.MAX_VALUE;
117          }
118       }
119    }
120
121    /**
122     * Change the context classloader to be where the idle remover was loaded from.<p>
123     *
124     * This avoids holding a reference to the caller's classloader which may be undeployed.
125     */

126    private void setupContextClassLoader()
127    {
128       // Could be null if loaded from system classloader
129
final ClassLoader JavaDoc cl = IdleRemover.class.getClassLoader();
130       if (cl == null)
131          return;
132       
133       SecurityManager JavaDoc sm = System.getSecurityManager();
134       if (sm == null)
135          Thread.currentThread().setContextClassLoader(cl);
136       
137       AccessController.doPrivileged(new PrivilegedAction JavaDoc()
138       {
139          public Object JavaDoc run()
140          {
141             Thread.currentThread().setContextClassLoader(cl);
142             return null;
143          }
144       });
145    }
146
147    /**
148     * Idle Remover background thread
149     */

150    private class IdleRemoverRunnable implements Runnable JavaDoc
151    {
152       public void run()
153       {
154          setupContextClassLoader();
155          
156          synchronized (pools)
157          {
158             while (true)
159             {
160                try
161                {
162                   pools.wait(interval);
163                   log.debug("run: IdleRemover notifying pools, interval: " + interval);
164                   for (Iterator JavaDoc i = pools.iterator(); i.hasNext(); )
165                      ((InternalManagedConnectionPool)i.next()).removeIdleConnections();
166                   next = System.currentTimeMillis() + interval;
167                   if (next < 0)
168                      next = Long.MAX_VALUE;
169                   
170                }
171                catch (InterruptedException JavaDoc ie)
172                {
173                   log.info("run: IdleRemover has been interrupted, returning");
174                   return;
175                }
176                catch (RuntimeException JavaDoc e)
177                {
178                   log.warn("run: IdleRemover ignored unexpected runtime exception", e);
179                }
180                catch (Error JavaDoc e)
181                {
182                   log.warn("run: IdleRemover ignored unexpected error", e);
183                }
184             }
185          }
186       }
187    }
188 }
189
Popular Tags