KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > scalagent > kjoram > util > Daemon


1 /*
2  * Copyright (C) 2002 - ScalAgent Distributed Technologies
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA.
18  *
19  * The present code contributor is ScalAgent Distributed Technologies.
20  *
21  * Contributor(s): Nicolas Tachker (ScalAgent)
22  */

23
24 package com.scalagent.kjoram.util;
25
26 import com.scalagent.kjoram.JoramTracing;
27
28 /**
29  * The Daemon class represents a basic active component in a server. It
30  * provides usefull code to start and safely stop inner Thread.
31  * <p>
32  * Main loop of daemon:
33  * <p><hr>
34  * <blockquote><pre>
35  * try {
36  * while (running) {
37  * canStop = true;
38  *
39  * // Get a notification, then execute the right reaction.
40  * try {
41  * // Get a request
42  * ...
43  * } catch (InterruptedException exc) {
44  * continue;
45  * }
46  *
47  * canStop = false;
48  *
49  * // executes the request
50  * ...
51  * }
52  * } finally {
53  * finish();
54  * }
55  * </pre></blockquote>
56  */

57 public abstract class Daemon implements Runnable JavaDoc {
58
59   /**
60    * Tests if this daemon is alive.
61    * @return true if this daemon is alive; false otherwise.
62    */

63   public synchronized boolean isRunning() {
64     return ((thread != null) && thread.isAlive());
65   }
66
67   /**
68    * Boolean variable used to stop the daemon properly. The daemon tests
69    * this variable between each request, and stops if it is false.
70    * @see start
71    * @see stop
72    */

73   protected volatile boolean running;
74   /**
75    * Boolean variable used to stop the daemon properly. If this variable
76    * is true then the daemon is waiting for a long time and it can interupted,
77    * else it handles a request and it will exit after (it tests the
78    * <code>{@link #running running}</code> variable between
79    * each reaction)
80    */

81   protected volatile boolean canStop;
82   /** The active component of this daemon. */
83   protected Thread JavaDoc thread = null;
84   /** The <code>daemon</code>'s name. */
85   private String JavaDoc name;
86   /** The <code>daemon</code>'s nature. */
87   private boolean daemon = false;
88   /** The <code>priority</code> that is assigned to the daemon. */
89   protected int priority = Thread.NORM_PRIORITY;
90
91   /**
92    * Returns this <code>daemon</code>'s name.
93    *
94    * @return this <code>daemon</code>'s name.
95    */

96   public final String JavaDoc getName() {
97     return name;
98   }
99
100   /**
101    * Returns a string representation of this daemon.
102    *
103    * @return A string representation of this daemon.
104    */

105   public String JavaDoc toString() {
106     StringBuffer JavaDoc strbuf = new StringBuffer JavaDoc();
107
108     strbuf.append(getName())
109       .append(" [").append(running).append("/")
110       .append(canStop).append("]");
111
112     if (thread != null) strbuf.append(" -> ").append(thread.isAlive());
113
114     return strbuf.toString();
115   }
116
117   /**
118    * Allocates a new Daemon object.
119    *
120    * @param name the name of the new Daemon
121    */

122   protected Daemon(String JavaDoc name) {
123     this.name = name;
124     running = false;
125     canStop = false;
126     thread = null;
127   }
128
129   public void setDaemon(boolean daemon) {
130     if (running || ((thread != null) && thread.isAlive())) {
131       throw new IllegalThreadStateException JavaDoc("already started");
132     }
133     this.daemon = daemon;
134   }
135
136   public void setPriority(int newPriority) {
137     if ((newPriority > Thread.MAX_PRIORITY) ||
138         (newPriority < Thread.MIN_PRIORITY)) {
139       throw new IllegalArgumentException JavaDoc();
140     }
141     if (running && (thread != null) && thread.isAlive())
142       thread.setPriority(newPriority);
143     priority = newPriority;
144   }
145
146   /**
147    * Causes this daemon to begin execution. A new thread is created to
148    * execute the run method.
149    *
150    * @exception IllegalThreadStateException
151    * If the daemon was already started.
152    */

153   public synchronized void start() {
154     if ((thread != null) && thread.isAlive()) {
155       if (JoramTracing.dbg)
156         JoramTracing.log(JoramTracing.WARN,
157                          getName() + ", already started.");
158       throw new IllegalThreadStateException JavaDoc("already started");
159     }
160
161     thread = new Thread JavaDoc(this);
162     //thread.setDaemon(daemon);
163
if (priority != Thread.NORM_PRIORITY)
164       thread.setPriority(priority);
165     running = true;
166     canStop = true;
167     thread.start();
168
169     if (JoramTracing.dbg)
170       JoramTracing.log(JoramTracing.DEBUG,
171                        getName() + ", started.");
172   }
173
174   /**
175    * Releases any resources attached to this daemon. Be careful, its method
176    * should be called more than one time.
177    */

178   protected abstract void close();
179
180   /**
181    * Interupts a thread that waits for long periods. In some cases, we must
182    * use application specific tricks. For example, if a thread is waiting on
183    * a known socket, we have to close the socket to cause the thread to return
184    * immediately. Unfortunately, there really isn't any technique that works
185    * in general.
186    */

187   protected abstract void shutdown();
188
189   /**
190    * Interrupts this daemon.
191    */

192 // public void interrupt() {
193
// thread.interrupt();
194
// }
195

196   final protected void finish() {
197     running = false;
198     close();
199     if (JoramTracing.dbg)
200       JoramTracing.log(JoramTracing.DEBUG,
201                        getName() + ", ended");
202   }
203
204   /**
205    * Forces the daemon to stop executing. This method notifies thread that
206    * it should stop running, if the thread is waiting it is first interupted
207    * then the shutdown method is called to close all ressources.
208    */

209   public synchronized void stop() {
210     if (JoramTracing.dbg)
211       JoramTracing.log(JoramTracing.DEBUG,
212                        getName() + ", stops.");
213     running = false;
214     if (thread != null) {
215       while (thread.isAlive()) {
216         if (canStop) {
217
218 // if (thread.isAlive())
219
// thread.interrupt();
220

221           shutdown();
222         }
223 // try {
224
// thread.join();
225
// } catch (InterruptedException exc) {
226
// continue;
227
// }
228
}
229       finish();
230       thread = null;
231     }
232   }
233 }
234
Popular Tags