KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > dream > control > lifecycle > ThreadCounterMixin


1 /**
2  * Dream
3  * Copyright (C) 2003-2004 INRIA Rhone-Alpes
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Contact: dream@objectweb.org
20  *
21  * Initial developer(s): Matthieu Leclercq
22  * Contributor(s):
23  */

24
25 package org.objectweb.dream.control.lifecycle;
26
27 import org.objectweb.fractal.api.Component;
28 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
29 import org.objectweb.fractal.api.factory.InstantiationException;
30 import org.objectweb.fractal.julia.InitializationContext;
31 import org.objectweb.fractal.julia.control.lifecycle.LifeCycleCoordinator;
32 import org.objectweb.util.monolog.api.BasicLevel;
33 import org.objectweb.util.monolog.api.Logger;
34
35 /**
36  * Life cycle mixin to be used with interceptor generated by
37  * {@link LifeCycleInterceptorGenerator}.
38  * <p>
39  * <p>
40  * <b>Requirements </b>
41  * <ul>
42  * <li>This mixin must be used with the
43  * {@link org.objectweb.fractal.julia.UseComponentMixin }mixin.</li>
44  * <li>This mixin must be used with the {@link SimpleLifeCycleControllerMixin}
45  * lifecycle controller implementation.</li>
46  * <li>This mixin must be used with the {@link LifeCycleInterceptorGenerator}
47  * interceptor generator.</li>
48  * </ul>
49  */

50 public abstract class ThreadCounterMixin implements LifeCycleCoordinator
51 {
52
53   /** The array of currently executing threads. */
54   protected Thread JavaDoc[] fcExecutingThreads;
55   /** The array of the invocation counter for each threads. */
56   protected int[] fcInvocationCounters;
57   /** The number of currently executing thread */
58   protected int fcNbExcutingThread;
59
60   protected LifeCycleCoordinator fcCoordinator;
61
62   // ---------------------------------------------------------------------------
63
// Fields and methods added and overriden by the mixin class
64
// ---------------------------------------------------------------------------
65

66   /**
67    * @see org.objectweb.fractal.julia.Controller#initFcController(InitializationContext)
68    */

69   public void initFcController(final InitializationContext ic)
70       throws InstantiationException JavaDoc
71   {
72
73     // intialize fields
74
fcExecutingThreads = new Thread JavaDoc[2];
75     fcInvocationCounters = new int[2];
76     fcNbExcutingThread = 0;
77
78     _super_initFcController(ic);
79   }
80
81   /**
82    * @see LifeCycleCoordinator#setFcStarted()
83    */

84   public boolean setFcStarted() throws IllegalLifeCycleException
85   {
86     synchronized (this)
87     {
88       if (_super_setFcStarted())
89       {
90         notifyAll();
91         return true;
92       }
93       return false;
94     }
95   }
96
97   /**
98    * @see LifeCycleCoordinator#setFcStopping(LifeCycleCoordinator)
99    */

100   public void setFcStopping(LifeCycleCoordinator coordinator)
101       throws IllegalLifeCycleException
102   {
103     synchronized (this)
104     {
105       _this_weaveableLCCLogger.log(BasicLevel.DEBUG, "Stopping component");
106       _this_weaveableFcState = 1;
107       fcCoordinator = coordinator;
108       if (!_this_isInactivated(coordinator))
109       {
110         for (int i = 0; i < fcExecutingThreads.length; i++)
111         {
112           // interrupt executing threads
113
if (fcExecutingThreads[i] != null)
114           {
115             fcExecutingThreads[i].interrupt();
116           }
117         }
118       }
119     }
120   }
121
122   /**
123    * @see LifeCycleCoordinator#setFcStopped()
124    */

125   public boolean setFcStopped() throws IllegalLifeCycleException
126   {
127     synchronized (this)
128     {
129       if (_super_setFcStopped())
130       {
131         fcCoordinator = null;
132         return true;
133       }
134       return false;
135     }
136   }
137
138   // ---------------------------------------------------------------------------
139
// Methods called by the associated interceptor
140
// ---------------------------------------------------------------------------
141

142   /**
143    * Registers the current thread has an executing thread. If it is already
144    * registered, increments it counter. If the component is started this method
145    * just registers the current thread. If the component is stopped, it waits
146    * until the component is restarted, ant then registers the current thread.
147    * Finally if the component is stopping, threr are two cases. If no thread is
148    * executing the component, this method asks the coordinator if the method
149    * call can be executed, or if it should be delayed until the component is
150    * restarted. The method then blocks or not, depending on the coordinator's
151    * response, before registering the current thread.
152    *
153    * @param s not used.
154    * @return the index of the current thread in the array of executing threads.
155    * This value is passed to the
156    * {@link #removeCurrentThread(String, int) }to executing thread.
157    */

158   public int addCurrentThread(String JavaDoc s)
159   {
160     synchronized (this)
161     {
162       boolean ok;
163       if (_this_weaveableFcState != 2)
164       {
165         do
166         {
167           if (_this_weaveableFcState == 0)
168           {
169             ok = false;
170           }
171           else if (_this_weaveableFcState == 1)
172           {
173             if (fcNbExcutingThread == 0)
174             {
175               ok = fcCoordinator.fcActivated(_this_getFcCoordinator());
176             }
177             else
178             {
179               ok = true;
180             }
181           }
182           else
183           {
184             ok = true;
185           }
186
187           if (!ok)
188           {
189             try
190             {
191               wait();
192             }
193             catch (InterruptedException JavaDoc e)
194             {
195
196             }
197           }
198         }
199         while (!ok);
200       }
201
202       return registerCurrentThread();
203     }
204   }
205
206   /**
207    * Unregister the current thread. Finally if the component is stoping, there
208    * are two cases. If the component is stopping, and no more thread is
209    * executing it, this method notifies the coordinator that the component has
210    * become inactive.
211    *
212    * @param s not used.
213    * @param i the index of the current thread in the array of executing threads.
214    */

215   public void removeCurrentThread(String JavaDoc s, int i)
216   {
217     synchronized (this)
218     {
219       unregisterCurrentThread(i);
220     }
221   }
222
223   /**
224    * Registers the current thread.
225    *
226    * @return the index of the current thread in the array of executing threads.
227    */

228   public int registerCurrentThread()
229   {
230     int freeIndex = -1;
231     Thread JavaDoc currentThread = Thread.currentThread();
232     for (int i = 0; i < fcExecutingThreads.length; i++)
233     {
234       Thread JavaDoc thread = fcExecutingThreads[i];
235       if (thread == currentThread)
236       {
237         fcInvocationCounters[i]++;
238         return i;
239       }
240       else if (thread == null)
241       {
242         freeIndex = i;
243       }
244     }
245     if (freeIndex == -1)
246     {
247       // no space left in arrays
248
Thread JavaDoc[] precThreads = fcExecutingThreads;
249       int[] precCounters = fcInvocationCounters;
250       fcExecutingThreads = new Thread JavaDoc[precThreads.length + 2];
251       fcInvocationCounters = new int[precThreads.length + 2];
252
253       System.arraycopy(precThreads, 0, fcExecutingThreads, 0,
254           precThreads.length);
255       System.arraycopy(precCounters, 0, fcInvocationCounters, 0,
256           precCounters.length);
257       freeIndex = precThreads.length;
258     }
259
260     fcExecutingThreads[freeIndex] = currentThread;
261     fcInvocationCounters[freeIndex] = 1;
262     fcNbExcutingThread++;
263     return freeIndex;
264   }
265
266   /**
267    * Unregisters current thread.
268    *
269    * @param i the index of the current thread in the array of executing threads.
270    */

271   public void unregisterCurrentThread(int i)
272   {
273     fcInvocationCounters[i]--;
274     if (fcInvocationCounters[i] == 0)
275     {
276       fcExecutingThreads[i] = null;
277       fcNbExcutingThread--;
278       _this_isInactivated(fcCoordinator);
279     }
280   }
281
282   /**
283    * Returns <code>true</code> If the component is stopping, and no more
284    * thread is executing it and super implementation returns <code>true</code>.
285    *
286    * @return <code>true</code> If the component is inactive
287    */

288   public boolean checkInactivity()
289   {
290     return _this_weaveableFcState != 2 && fcNbExcutingThread == 0
291         && _super_checkInactivity();
292   }
293
294   // ---------------------------------------------------------------------------
295
// Fields and methods required by the mixin class in the base class
296
// ---------------------------------------------------------------------------
297

298   /**
299    * The <code>weaveableC</code> field required by this mixin. This field is
300    * supposed to reference the {@link Component}interface of the component to
301    * which this controller object belongs.
302    */

303   public Component _this_weaveableC;
304
305   /**
306    * the <code>weaveableFcState</code> field reqired by this mixin. This field
307    * is supposed to reference the current state of the component lifecycle.
308    *
309    * @see SimpleLifeCycleControllerMixin#weaveableFcState
310    */

311   public int _this_weaveableFcState;
312
313   /**
314    * The <tt>weaveableLCCLogger</tt> field required by this mixin. This field
315    * is supposed to reference the {@link Logger }of this controller.
316    */

317   public Logger _this_weaveableLCCLogger;
318
319   /**
320    * The {@link LifeCycleCoordinator#setFcStarted() }method overriden by this
321    * mixin.
322    *
323    * @see LifeCycleCoordinator#setFcStarted()
324    */

325   public abstract boolean _super_setFcStarted()
326       throws IllegalLifeCycleException;
327
328   /**
329    * The {@link LifeCycleCoordinator#setFcStopped() }method overriden by this
330    * mixin.
331    *
332    * @see LifeCycleCoordinator#setFcStopped()
333    */

334   public abstract boolean _super_setFcStopped()
335       throws IllegalLifeCycleException;
336
337   /**
338    * The <code>checkInactivity</code> method overriden by this mixin. This
339    * method is supposed to work as this
340    * {@link SimpleLifeCycleControllerMixin#checkInactivity() }method.
341    *
342    * @see SimpleLifeCycleControllerMixin#checkInactivity()
343    */

344   public abstract boolean _super_checkInactivity();
345
346   /**
347    * The <code>getFcCoordinator</code> method overriden by this mixin. This
348    * method is supposed to work as this
349    * {@link SimpleLifeCycleControllerMixin#getFcCoordinator() }method.
350    *
351    * @see SimpleLifeCycleControllerMixin#getFcCoordinator()
352    */

353   public abstract LifeCycleCoordinator _this_getFcCoordinator();
354
355   /**
356    * The <code>isInactivated</code> method used by this mixin. This method is
357    * supposed to work as this
358    * {@link SimpleLifeCycleControllerMixin#isInactivated }method.
359    *
360    * @see SimpleLifeCycleControllerMixin#isInactivated
361    */

362   public abstract boolean _this_isInactivated(LifeCycleCoordinator coordinator);
363
364   /**
365    * The {@link org.objectweb.fractal.julia.Controller#initFcController }method
366    * overriden by this mixin.
367    *
368    * @see org.objectweb.fractal.julia.Controller#initFcController(InitializationContext)
369    */

370   public abstract void _super_initFcController(InitializationContext ic)
371       throws InstantiationException JavaDoc;
372 }
Popular Tags