1 /*********************************************************************
2 Copyright 2012, Ralph Ronnquist.
4 This file is part of GORITE.
6 GORITE is free software: you can redistribute it and/or modify it
7 under the terms of the Lesser GNU General Public License as published
8 by the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GORITE is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the Lesser GNU General Public
17 License along with GORITE. If not, see <http://www.gnu.org/licenses/>.
18 **********************************************************************/
20 package com.intendico.gorite;
23 * This is an Executor extension intended for applications containing
24 * multiple models (i.e., Executors), and multiple threads to execute
25 * them. The PoolExecutor is tied to a {@link
26 * java.util.concurrent.Executor} on concstruction. It adds itself for
27 * running whenever it gets runnable by signalling, or any performer
28 * ended in STOPPED rather than BLOCKED. This approach allows an
29 * execution pool of many threads, where one thread at a time is used
30 * for executing all each Executor's performers once, then
31 * interleaving the models in between these one-shot runs.
33 public class PoolExecutor extends Executor {
36 * Cache of the execution queue interface.
38 private java.util.concurrent.Executor runner;
41 * Control flag for capturing signal calls during performer
42 * execution. This is reset by the {@link #run()} method before it
43 * executes performers, and set by the {@link #signal()} method
46 private boolean signaled = false;
49 * Constructor with a given {@link java.util.concurrent.Executor}.
51 public PoolExecutor(java.util.concurrent.Executor x) {
52 super( "PoolExecutor" );
58 * Utility method to "tickle" the executor with, just in case it
59 * is idle. Unless marked as running, this Executor is entered
60 * into the execution queue (and marked as running).
62 synchronized public void signal() {
66 runner.execute( this );
72 * Overrides {@link Executor#run()} for a one-shot execution of
73 * all performers. If any performer ends in STOPPED rather than
74 * BLOCKED, or there is a {@link #signal()} while the execution is
75 * in progress, then this Executor is re-entered into the
80 if ( runPerformersOnce() != Goal.States.BLOCKED ) {
81 runner.execute( this ); // continue asap
85 synchronized ( this ) {
86 b = running = signaled;
89 runner.execute( this ); // continue asap