KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > driver > ConnectionClosingThread


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: sequoia@continuent.org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * Initial developer(s): Emmanuel Cecchet.
20  * Contributor(s): ______________________________________.
21  */

22
23 package org.continuent.sequoia.driver;
24
25 import java.util.ArrayList JavaDoc;
26
27 /**
28  * The <code>ConnectionClosingThread</code> wakes up every 5 seconds when
29  * close() has been called on a connection and it frees the connection if it has
30  * not been reused.
31  *
32  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
33  * @version 1.0
34  */

35 public class ConnectionClosingThread extends Thread JavaDoc
36 {
37   /* wait time before closing a connection in ms */
38   private static final int WAIT_TIME = 5000;
39
40   private Driver driver;
41   private ArrayList JavaDoc pendingConnectionClosing;
42
43   /**
44    * Builds a new ConnectionClosingThread
45    *
46    * @param driver The driver that created us
47    */

48   public ConnectionClosingThread(Driver driver)
49   {
50     super("ConnectionClosingThread");
51     this.driver = driver;
52     this.pendingConnectionClosing = driver.pendingConnectionClosing;
53     driver.connectionClosingThreadisAlive = true;
54   }
55
56   /**
57    * The connection closing thread wakes up every WAIT_TIME seconds when close()
58    * has been called on a connection and it frees the connection if it has not
59    * been reused.
60    */

61   public void run()
62   {
63     try
64     {
65       Connection firstConnectionToClose = null;
66       Connection lastConnectionToClose = null;
67       int pendingConnectionSize;
68       ArrayList JavaDoc closingList = new ArrayList JavaDoc();
69       boolean killed = false;
70
71       while (!killed)
72       {
73         synchronized (pendingConnectionClosing)
74         {
75           pendingConnectionSize = pendingConnectionClosing.size();
76           if (pendingConnectionSize == 0)
77             break;
78
79           try
80           {
81             // Look at the connections in the queue before sleeping
82
firstConnectionToClose = (Connection) pendingConnectionClosing
83                 .get(0);
84             lastConnectionToClose = (Connection) pendingConnectionClosing
85                 .get(pendingConnectionSize - 1);
86
87             // Sleep
88
pendingConnectionClosing.wait(WAIT_TIME);
89           }
90           catch (InterruptedException JavaDoc ignore)
91           {
92           }
93
94           pendingConnectionSize = pendingConnectionClosing.size();
95           // Exit, no more connections
96
if (pendingConnectionSize == 0)
97             break;
98
99           // Compare the queue now with its state when we got to sleep
100
if (firstConnectionToClose == pendingConnectionClosing.get(0))
101           { // Ok, the connection has not been reused, let's close it
102
if (lastConnectionToClose == (Connection) pendingConnectionClosing
103                 .get(pendingConnectionSize - 1))
104             { // No connection has been reused, remove them all
105
closingList.addAll(pendingConnectionClosing);
106               pendingConnectionClosing.clear();
107               killed = true; // Let's die, there are no more connections
108
}
109             else
110               // Close only the first connection
111
closingList.add(pendingConnectionClosing.remove(0));
112           }
113         }
114
115         // Effectively close the connections outside the synchronized block
116
while (!closingList.isEmpty())
117           closeConnection((Connection) closingList.remove(0));
118       }
119     }
120     catch (RuntimeException JavaDoc e)
121     {
122       e.printStackTrace();
123     }
124     finally
125     {
126       synchronized (pendingConnectionClosing)
127       {
128         driver.connectionClosingThreadisAlive = false;
129       }
130     }
131   }
132
133   /**
134    * Closes a connection. This cleanup should belong to the underlying class.
135    *
136    * @param c the connection to close
137    */

138   private void closeConnection(Connection c)
139   {
140     try
141     {
142       // Free remote resources
143
if (c.socketOutput != null)
144       {
145         c.reallyClose();
146         // The following probably better belongs to Connection.reallyClose(),
147
// so there would be no external class messing up with c.socketXXXput,,
148
// and Connection can close itself.
149
c.socketOutput.flush();
150         if (c.socketInput != null)
151         { // Wait for the controller to receive the connection and close the
152
// stream. If we do not wait for the controller ack, the connection is
153
// closed on the controller before the closing is handled which
154
// results in an ugly warning message on the controller side. We are
155
// not in a hurry when closing the connection so let do the things
156
// nicely!
157
c.socketInput.readBoolean();
158           c.socketInput.close();
159         }
160         c.socketOutput.close();
161       }
162
163       if (c.socket != null)
164         c.socket.close();
165     }
166     catch (Exception JavaDoc ignore)
167     {
168     }
169   }
170
171 }
Popular Tags