KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > dream > control > activity > task > ThreadPerTaskTaskManagerControllerMixin


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): Vivien Quema
22  * Contributor(s): Matthieu Leclercq
23  */

24
25 package org.objectweb.dream.control.activity.task;
26
27 import java.util.HashMap JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import org.objectweb.dream.control.activity.scheduler.ForwarderSchedulerImpl;
31 import org.objectweb.dream.control.activity.scheduler.Scheduler;
32 import org.objectweb.dream.control.activity.task.thread.ThreadPoolController;
33 import org.objectweb.dream.control.activity.task.thread.ThreadTask;
34 import org.objectweb.dream.util.Error;
35 import org.objectweb.fractal.api.Component;
36 import org.objectweb.fractal.api.Interface;
37 import org.objectweb.fractal.api.NoSuchInterfaceException;
38 import org.objectweb.fractal.api.control.ContentController;
39 import org.objectweb.fractal.api.control.IllegalBindingException;
40 import org.objectweb.fractal.api.control.IllegalContentException;
41 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
42 import org.objectweb.fractal.api.factory.InstantiationException;
43 import org.objectweb.fractal.julia.InitializationContext;
44 import org.objectweb.fractal.util.Fractal;
45 import org.objectweb.util.monolog.api.BasicLevel;
46 import org.objectweb.util.monolog.api.Logger;
47
48 /**
49  * Provides a basic implementation of the
50  * {@link org.objectweb.dream.control.activity.task.TaskManagerController}
51  * interface. Each registered task has its own scheduler and thread task. Two
52  * types of thread tasks are available :
53  * <ul>
54  * <li>Mono threaded task (default): the {@link #registerTask}method returns
55  * <code>null</code></li>
56  * <li>Thread pool task: used if registration hints contain a
57  * <code>"thread"</code> key mapped to the <code>"pool"</code> value. In
58  * addition the pool capacity can be specified with a
59  * <code>"threadPool.capacity"</code> key mapped to the required
60  * {@link Integer }value. In this case, the {@link #registerTask}method
61  * returns the
62  * {@link org.objectweb.dream.control.activity.task.thread.ThreadPoolController}
63  * control interface of the thread pool component.</li>
64  * </ul>
65  * <p>
66  *
67  * @see org.objectweb.dream.control.activity.task.thread.ThreadTask
68  * @see org.objectweb.dream.control.activity.task.thread.ThreadPoolTask
69  * @see ThreadPoolController#setCapacity(int)
70  */

71
72 public abstract class ThreadPerTaskTaskManagerControllerMixin
73     implements
74       TaskManagerController,
75       TaskStoppedListener
76 {
77
78   /** The map of registered tasks and the thread they are bound to. */
79   protected Map JavaDoc tasks;
80   /** The map of the interrupted tasks. */
81   protected Map JavaDoc interruptedTasks;
82
83   // ---------------------------------------------------------------------------
84
// private constructor
85
// ---------------------------------------------------------------------------
86

87   private ThreadPerTaskTaskManagerControllerMixin()
88   {
89   }
90
91   // ---------------------------------------------------------------------------
92
// Fields and methods added and overriden by the mixin class
93
// ---------------------------------------------------------------------------
94

95   /**
96    * @see org.objectweb.fractal.julia.Controller#initFcController(InitializationContext)
97    */

98   public void initFcController(final InitializationContext ic)
99       throws InstantiationException JavaDoc
100   {
101
102     tasks = new HashMap JavaDoc();
103     interruptedTasks = new HashMap JavaDoc();
104
105     _super_initFcController(ic);
106   }
107
108   // ---------------------------------------------------------------------------
109
// Implementation of the TaskManagerController interface
110
// ---------------------------------------------------------------------------
111

112   /**
113    * @see TaskManagerController#registerTask(Task, Map)
114    */

115   public synchronized Object JavaDoc registerTask(Task task, Map JavaDoc hints)
116       throws IllegalTaskException
117   {
118     if (tasks.containsKey(task))
119     {
120       throw new IllegalTaskException(task, "The task is already registred",
121           null);
122     }
123
124     // Add task component.
125
String JavaDoc controllerDesc = (String JavaDoc) hints.get("taskControllerDesc");
126     Component componentTask;
127     try
128     {
129       componentTask = Util.createTask(task, (controllerDesc == null)
130           ? "taskPrimitive"
131           : controllerDesc);
132     }
133     catch (InstantiationException JavaDoc e)
134     {
135       throw new IllegalTaskException(null,
136           "Unable to instantiate task component", e);
137     }
138     try
139     {
140       _this_weaveableCC.addFcSubComponent(componentTask);
141     }
142     catch (IllegalContentException e)
143     {
144       throw new IllegalTaskException(task,
145           "Unable to add task component in activity manager", e);
146     }
147     catch (IllegalLifeCycleException e)
148     {
149       throw new IllegalTaskException(task,
150           "Unable to add task component in activity manager", e);
151     }
152     String JavaDoc taskName = null;
153     try
154     {
155       taskName = Fractal.getNameController(componentTask).getFcName();
156     }
157     catch (NoSuchInterfaceException e1)
158     {
159       // ignore.
160
}
161
162     // Create the thread task component.
163
Component thread;
164     ThreadPoolController returnObject = null;
165     String JavaDoc s = (String JavaDoc) hints.get("thread");
166     if (s != null && "pool".equals(s))
167     {
168       _this_weaveableTMCLogger.log(BasicLevel.DEBUG, "Create thread pool task");
169
170       try
171       {
172         thread = Util.createThreadPoolTask((taskName == null)
173             ? "threadPoolTask"
174             : taskName + "-threadPoolTask");
175       }
176       catch (InstantiationException JavaDoc e)
177       {
178         throw new IllegalTaskException(task,
179             "Unable to create thread pool task component in activity manager",
180             e);
181       }
182
183       try
184       {
185         returnObject = (ThreadPoolController) thread
186             .getFcInterface("thread-pool-controller");
187       }
188       catch (NoSuchInterfaceException e)
189       {
190         Error.bug(_this_weaveableTMCLogger, e);
191       }
192       // set initial capacity;
193
Integer JavaDoc capacity = (Integer JavaDoc) hints.get("threadPool.capacity");
194       if (capacity != null)
195       {
196         returnObject.setCapacity(capacity.intValue());
197       }
198     }
199     else
200     {
201       _this_weaveableTMCLogger
202           .log(BasicLevel.DEBUG, "Create basic thread task");
203       try
204       {
205         thread = Util.createTask(new ThreadTask(), "threadPrimitive");
206       }
207       catch (InstantiationException JavaDoc e)
208       {
209         throw new IllegalTaskException(task,
210             "Unable to create thread task component in activity manager", e);
211       }
212       returnObject = null;
213     }
214
215     if (taskName != null)
216     {
217       try
218       {
219         Fractal.getNameController(thread).setFcName(taskName + "-thread");
220       }
221       catch (NoSuchInterfaceException e2)
222       {
223         // ignore.
224
}
225     }
226
227     // Add the thread task component.
228
try
229     {
230       _this_weaveableCC.addFcSubComponent(thread);
231     }
232     catch (IllegalContentException e)
233     {
234       throw new IllegalTaskException(task,
235           "Unable to add thread task component in activity manager", e);
236     }
237     catch (IllegalLifeCycleException e)
238     {
239       throw new IllegalTaskException(task,
240           "Unable to add thread task component in activity manager", e);
241     }
242
243     // Create and add the forwarder scheduler
244
Component forwarderScheduler;
245     try
246     {
247       forwarderScheduler = Util.createScheduler(new ForwarderSchedulerImpl(),
248           (taskName == null) ? "scheduler" : taskName + "-scheduler");
249     }
250     catch (InstantiationException JavaDoc e)
251     {
252       throw new IllegalTaskException(task,
253           "Unable to create scheduler component in activity manager", e);
254     }
255     if (taskName != null)
256     {
257       try
258       {
259         Fractal.getNameController(forwarderScheduler).setFcName(
260             taskName + "-scheduler");
261       }
262       catch (NoSuchInterfaceException e2)
263       {
264         // ignore.
265
}
266     }
267
268     try
269     {
270       _this_weaveableCC.addFcSubComponent(forwarderScheduler);
271     }
272     catch (IllegalContentException e)
273     {
274       throw new IllegalTaskException(task,
275           "Unable to add scheduler component in activity manager", e);
276     }
277     catch (IllegalLifeCycleException e)
278     {
279       throw new IllegalTaskException(task,
280           "Unable to add scheduler component in activity manager", e);
281     }
282
283     // bind the thread task to the scheduler
284
try
285     {
286       Fractal.getBindingController(thread).bindFc(Scheduler.ITF_NAME,
287           forwarderScheduler.getFcInterface(Scheduler.ITF_NAME));
288       // bind the scheduler to the task
289
Fractal.getBindingController(forwarderScheduler).bindFc(Task.ITF_NAME,
290           componentTask.getFcInterface(Task.ITF_NAME));
291     }
292     catch (NoSuchInterfaceException e)
293     {
294       Error.bug(_this_weaveableTMCLogger, e);
295     }
296     catch (IllegalBindingException e)
297     {
298       Error.bug(_this_weaveableTMCLogger, e);
299     }
300     catch (IllegalLifeCycleException e)
301     {
302       Error.bug(_this_weaveableTMCLogger, e);
303     }
304     try
305     {
306       // start all the components
307
Fractal.getLifeCycleController(thread).startFc();
308     }
309     catch (IllegalLifeCycleException e)
310     {
311       throw new IllegalTaskException(task,
312           "unable to start thread task component", e);
313     }
314     catch (NoSuchInterfaceException e)
315     {
316       Error.bug(_this_weaveableTMCLogger, e);
317     }
318
319     tasks.put(task, new Component[]{componentTask, forwarderScheduler, thread});
320
321     return returnObject;
322
323   }
324
325   /**
326    * @see TaskManagerController#unregisterTask(Task)
327    */

328   public synchronized void unregisterTask(Task task)
329       throws IllegalTaskException
330   {
331     if (!tasks.containsKey(task))
332     {
333       throw new IllegalTaskException(task, "The task is not registered", null);
334     }
335     // retrieve the forwarder scheduler and the thread associated to the
336
// task
337
Component[] components = (Component[]) tasks.get(task);
338     Component componentTask = components[0];
339     Component forwarderScheduler = components[1];
340     Component thread = components[2];
341     removeTask(task, componentTask, forwarderScheduler, thread);
342     tasks.remove(task);
343   }
344
345   /**
346    * @see TaskManagerController#interruptTask(Task, TaskStoppedListener)
347    */

348   public synchronized void interruptTask(Task task, TaskStoppedListener listener)
349       throws IllegalTaskException
350   {
351     if (!tasks.containsKey(task))
352     {
353       throw new IllegalTaskException(task, "The task is not registered", null);
354     }
355     // retrieve the forwarder scheduler and the thread associated to the
356
// task
357
Component[] components = (Component[]) tasks.get(task);
358     Component thread = components[2];
359     Object JavaDoc[] taskStatus = new Object JavaDoc[]{task, listener, components[0],
360         components[1]};
361     interruptedTasks.put(thread, taskStatus);
362     try
363     {
364       ((TaskLifeCycleController) Fractal.getLifeCycleController(thread))
365           .asyncStop(this);
366     }
367     catch (NoSuchInterfaceException e)
368     {
369       // can't happend since thread has already been started.
370
Error.bug(_this_weaveableTMCLogger, e);
371     }
372   }
373
374   /**
375    * @see TaskManagerController#getTasks()
376    */

377   public Task[] getTasks()
378   {
379     if (tasks == null)
380     {
381       return new Task[0];
382     }
383     return (Task[]) tasks.keySet().toArray(new Task[tasks.size()]);
384   }
385
386   // ---------------------------------------------------------------------------
387
// Implementation of the TaskManagerController interface
388
// ---------------------------------------------------------------------------
389

390   /**
391    * @see TaskStoppedListener#taskStopped(Task)
392    */

393   public void taskStopped(Task thread)
394   {
395     Task task;
396     TaskStoppedListener listener;
397     synchronized (this)
398     {
399       Component threadComponent = ((Interface) thread).getFcItfOwner();
400       Object JavaDoc[] taskStatus = (Object JavaDoc[]) interruptedTasks.get(threadComponent);
401       task = (Task) taskStatus[0];
402       listener = (TaskStoppedListener) taskStatus[1];
403       Component componentTask = (Component) taskStatus[2];
404       Component forwarderScheduler = (Component) taskStatus[3];
405       try
406       {
407         removeTask(task, componentTask, forwarderScheduler, threadComponent);
408       }
409       catch (IllegalTaskException e)
410       {
411         Error.bug(_this_weaveableTMCLogger, e);
412       }
413       interruptedTasks.remove(threadComponent);
414     }
415     listener.taskStopped(task);
416   }
417
418   // ---------------------------------------------------------------------------
419
// Utility method
420
// ---------------------------------------------------------------------------
421

422   /**
423    * Removes a task from this composite component.
424    *
425    * @param task the registered task.
426    * @param componentTask the task component.
427    * @param forwarderScheduler the scheduler of the task.
428    * @param thread the thread executing the task.
429    * @throws IllegalTaskException if an error occurs.
430    */

431   public void removeTask(Task task, Component componentTask,
432       Component forwarderScheduler, Component thread)
433       throws IllegalTaskException
434   {
435     try
436     {
437       // stop, unbind and remove the thread
438
Fractal.getLifeCycleController(thread).stopFc();
439     }
440     catch (IllegalLifeCycleException e)
441     {
442       throw new IllegalTaskException(task,
443           "unable to stop thread task component", e);
444     }
445     catch (NoSuchInterfaceException e)
446     {
447       Error.bug(_this_weaveableTMCLogger, e);
448     }
449     // stop, unbind and remove the scheduler
450
try
451     {
452       Fractal.getBindingController(thread).unbindFc(Scheduler.ITF_NAME);
453       _this_weaveableCC.removeFcSubComponent(thread);
454       Fractal.getBindingController(forwarderScheduler).unbindFc(Task.ITF_NAME);
455       _this_weaveableCC.removeFcSubComponent(forwarderScheduler);
456       // remove the task
457
_this_weaveableCC.removeFcSubComponent(componentTask);
458     }
459     catch (NoSuchInterfaceException e)
460     {
461       Error.bug(_this_weaveableTMCLogger, e);
462     }
463     catch (IllegalBindingException e)
464     {
465       Error.bug(_this_weaveableTMCLogger, e);
466     }
467     catch (IllegalLifeCycleException e)
468     {
469       Error.bug(_this_weaveableTMCLogger, e);
470     }
471     catch (IllegalContentException e)
472     {
473       Error.bug(_this_weaveableTMCLogger, e);
474     }
475   }
476
477   // ---------------------------------------------------------------------------
478
// Fields and methods required by the mixin class in the base class
479
// ---------------------------------------------------------------------------
480

481   /**
482    * The <tt>weaveableTMCLogger</tt> field required by this mixin. This field
483    * is supposed to reference the {@link Logger }of this controller.
484    */

485   public Logger _this_weaveableTMCLogger;
486
487   /**
488    * The {@link ContentController }interface of the component to which this
489    * controller object belongs.
490    */

491   public ContentController _this_weaveableCC;
492
493   /**
494    * The {@link org.objectweb.fractal.julia.Controller#initFcController }method
495    * overriden by this mixin.
496    *
497    * @see org.objectweb.fractal.julia.Controller#initFcController(InitializationContext)
498    */

499   public abstract void _super_initFcController(InitializationContext ic)
500       throws InstantiationException JavaDoc;
501 }
Popular Tags