/*
 *  ZThreads, a platform-independant, multithreading and 
 *  synchroniation library
 *
 *  Copyright (C) 2000-2002, Eric Crahen, See LGPL.TXT for details
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 *  SUNY @ Buffalo, hereby disclaims all copyright interest in the
 *  ZThreads library written by Eric Crahen
 */

#ifndef __ZTEXECUTOR_H__
#define __ZTEXECUTOR_H__

#include "zthread/ZThread.h"
#include "zthread/Cancelable.h"
#include "zthread/Thread.h"

namespace ZThread {


/**
 * @class Executor
 *
 * @author Eric Crahen <crahen@cse.buffalo.edu>
 * @date <2002-03-04T20:30:34-0500>
 * @version 1.3.0
 *
 * This interface defines the basic outline needed to implement 
 * a LWP (light-weigh-process) execution mechanism. 
 *
 * An executor allows the efficent execution of a number of small 
 * unrelated 'Runnable' tasks, or LWP's without the over head of a 
 * large number of syncronization controls needed in a thread per task
 * solution.
 * 
 * This is a very nice way to share synchronization resources and to 
 * insert of layer of abstraction between a task and how that task is
 * executed.
 *
 * In general, executors queue tasks for execution by another thread or 
 * by a pool of threads. The queueing of task allows for a good deal of 
 * control over the order of execution.
 * 
 */
class ZTHREAD_API Executor : public Cancelable {
public:

  /**
   * Destroy Executor object
   */
  virtual ~Executor() throw() {}

  /**
   * Enqueue another task for execution.
   *
   * @param Runnable* task - task to execute 
   * NOTE: this bestows ownership of the task upon the executor
   * and so the executor will be responsible for deleting task items.
   * You should take this into account when submitting tasks
   *
   * @exception InterruptedException 
   *
   * @pre The executor must not be canceled. A canceled
   * executor will ignore execute() requests.
   *
   * @post The given task will be executed as soon as 
   * possible by the executor
   */
  virtual void execute(Runnable* task)
    throw(Synchronization_Exception) = 0;


  /**
   * Stop the execution of additonal tasks by this executor.
   * After this method has be invoked then the Executor will
   * completed when the last task it was previously assigned is 
   * completed. 
   *
   * @exception InterruptedException 
   * 
   * @post the executor no longer accepts new tasks. At this point
   * the executor has a limited lifetime and is safe to join
   */
  virtual void cancel() 
    throw(Synchronization_Exception) = 0;

  /**
   * Wait for this Executor to complete. The calling thread is
   * blocked until the last task has been completed by this executor
   * or until the calling thread has been interrupted.
   *
   * @exception InterruptedException 
   */
  virtual void join() 
    throw(Synchronization_Exception) = 0;

  /**
   * Block until this executor has become available to run new tasks.
   *
   * This does not garuntee that another thread won't have submitted a
   * task before some action is taken in response to this. However, it
   * is useful as a general hueristic
   *
   * @return bool
   * @exception InterruptedException 
   */
  virtual bool available() 
    throw(Synchronization_Exception) = 0;

  /**
   * Count of active threads operation on behalf of this executor
   *
   * This does not garuntee that another thread won't have submitted a
   * task that changes the number of executing threads before some action 
   * is taken in response to this. However, it is useful as a general 
   * hueristic
   * 
   * @return unsigned int
   * @exception InterruptedException 
   */ 
  virtual unsigned int threadCount()
    throw(Synchronization_Exception) = 0;

};

};

#endif
