KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jmx > remote > internal > ClientCommunicatorAdmin


1 /*
2  * @(#)ClientCommunicatorAdmin.java 1.14 04/05/12
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.jmx.remote.internal;
9
10 import java.io.IOException JavaDoc;
11 import java.io.InterruptedIOException JavaDoc;
12
13 import com.sun.jmx.remote.util.ClassLogger;
14 import com.sun.jmx.remote.util.EnvHelp;
15
16 public abstract class ClientCommunicatorAdmin {
17     public ClientCommunicatorAdmin(long period) {
18     this.period = period;
19
20     if (period > 0) {
21         checker = new Checker();
22
23         Thread JavaDoc t = new Thread JavaDoc(checker);
24         t.setDaemon(true);
25         t.start();
26     } else
27         checker = null;
28     }
29
30     /**
31      * Called by a client to inform of getting an IOException.
32      */

33     public void gotIOException (IOException JavaDoc ioe) throws IOException JavaDoc {
34     restart(ioe);
35     }
36
37     /**
38      * Called by this class to check a client connection.
39      */

40     protected abstract void checkConnection() throws IOException JavaDoc;
41
42     /**
43      * Tells a client to re-start again.
44      */

45     protected abstract void doStart() throws IOException JavaDoc;
46
47     /**
48      * Tells a client to stop becaue failing to call checkConnection.
49      */

50     protected abstract void doStop();
51
52     /**
53      * Terminates this object.
54      */

55     public void terminate() {
56     synchronized(lock) {
57         if (state == TERMINATED) {
58         return;
59         }
60
61         state = TERMINATED;
62
63         lock.notifyAll();
64
65         if (checker != null)
66         checker.stop();
67     }
68     }
69
70     private void restart(IOException JavaDoc ioe) throws IOException JavaDoc {
71     // check state
72
synchronized(lock) {
73         if (state == TERMINATED) {
74         throw new IOException JavaDoc("The client has been closed.");
75         } else if (state == FAILED) { // already failed to re-start by another thread
76
throw ioe;
77         } else if (state == RE_CONNECTING) {
78         // restart process has been called by another thread
79
// we need to wait
80
while(state == RE_CONNECTING) {
81             try {
82             lock.wait();
83             } catch (InterruptedException JavaDoc ire) {
84             // be asked to give up
85
InterruptedIOException JavaDoc iioe = new InterruptedIOException JavaDoc(ire.toString());
86             EnvHelp.initCause(iioe, ire);
87
88             throw iioe;
89             }
90         }
91
92         if (state == TERMINATED) {
93             throw new IOException JavaDoc("The client has been closed.");
94         } else if (state != CONNECTED) {
95             // restarted is failed by another thread
96
throw ioe;
97         }
98         } else {
99         state = RE_CONNECTING;
100         lock.notifyAll();
101         }
102     }
103
104     // re-starting
105
try {
106         doStart();
107         synchronized(lock) {
108         if (state == TERMINATED) {
109             throw new IOException JavaDoc("The client has been closed.");
110         }
111
112         state = CONNECTED;
113
114         lock.notifyAll();
115         }
116
117         return;
118     } catch (Exception JavaDoc e) {
119         logger.warning("restart", "Failed to restart: " + e);
120         logger.debug("restart",e);
121
122         synchronized(lock) {
123         if (state == TERMINATED) {
124             throw new IOException JavaDoc("The client has been closed.");
125         }
126
127         state = FAILED;
128
129         lock.notifyAll();
130         }
131
132         try {
133         doStop();
134         } catch (Exception JavaDoc eee) {
135         // OK.
136
// We know there is a problem.
137
}
138
139         terminate();
140
141         throw ioe;
142     }
143     }
144
145 // --------------------------------------------------------------
146
// private varaibles
147
// --------------------------------------------------------------
148
private class Checker implements Runnable JavaDoc {
149     public void run() {
150         myThread = Thread.currentThread();
151
152         while (state != TERMINATED && !myThread.isInterrupted()) {
153         try {
154             Thread.sleep(period);
155         } catch (InterruptedException JavaDoc ire) {
156             // OK.
157
// We will check the state at the following steps
158
}
159
160         if (state == TERMINATED || myThread.isInterrupted()) {
161             break;
162         }
163
164         try {
165             checkConnection();
166         } catch (Exception JavaDoc e) {
167             synchronized(lock) {
168             if (state == TERMINATED || myThread.isInterrupted()) {
169                 break;
170             }
171             }
172
173             e = (Exception JavaDoc)EnvHelp.getCause(e);
174
175             if (e instanceof IOException JavaDoc &&
176             !(e instanceof InterruptedIOException JavaDoc)) {
177             try {
178                 restart((IOException JavaDoc)e);
179             } catch (Exception JavaDoc ee) {
180                 logger.warning("Checker-run",
181                        "Failed to check connection: "+ e);
182                 logger.warning("Checker-run", "stopping");
183                 logger.debug("Checker-run",e);
184                 
185                 break;
186             }
187             } else {
188             logger.warning("Checker-run",
189                      "Failed to check the connection: " + e);
190             logger.debug("Checker-run",e);
191
192             // XXX stop checking?
193

194             break;
195             }
196         }
197         }
198
199         if (logger.traceOn()) {
200         logger.trace("Checker-run", "Finished.");
201         }
202     }
203
204     private void stop() {
205         if (myThread != null && myThread != Thread.currentThread()) {
206         myThread.interrupt();
207         }
208     }
209
210     private Thread JavaDoc myThread;
211     }
212
213 // --------------------------------------------------------------
214
// private variables
215
// --------------------------------------------------------------
216
private final Checker checker;
217     private long period;
218
219     // state
220
private final static int CONNECTED = 0;
221     private final static int RE_CONNECTING = 1;
222     private final static int FAILED = 2;
223     private final static int TERMINATED = 3;
224
225     private int state = CONNECTED;
226
227     private final int[] lock = new int[0];
228
229     private static final ClassLogger logger =
230     new ClassLogger("javax.management.remote.misc",
231             "ClientCommunicatorAdmin");
232 }
233
Popular Tags