view dwtx/core/runtime/jobs/IJobManager.d @ 122:9d0585bcb7aa

Add core.jobs package
author Frank Benoit <benoit@tionex.de>
date Tue, 12 Aug 2008 02:34:21 +0200
parents
children 862b05e0334a
line wrap: on
line source

/*******************************************************************************
 * Copyright (c) 2003, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 * Port to the D programming language:
 *     Frank Benoit <benoit@tionex.de>
 *******************************************************************************/
module dwtx.core.runtime.jobs.IJobManager;

import dwt.dwthelper.utils;

import dwtx.core.runtime.IProgressMonitor;
import dwtx.core.runtime.OperationCanceledException;
import dwtx.core.runtime.jobs.IJobChangeListener;
import dwtx.core.runtime.jobs.ISchedulingRule;
import dwtx.core.runtime.jobs.Job;
import dwtx.core.runtime.jobs.ILock;
import dwtx.core.runtime.jobs.LockListener;

import dwtx.core.runtime.jobs.ProgressProvider;
import tango.core.Thread;

/**
 * The job manager provides facilities for scheduling, querying, and maintaining jobs
 * and locks.  In particular, the job manager provides the following services:
 * <ul>
 * <li>Maintains a queue of jobs that are waiting to be run.  Items can be added to
 * the queue using the <code>schedule</code> method.</li>
 * <li>Allows manipulation of groups of jobs called job families.  Job families can
 * be canceled, put to sleep, or woken up atomically.  There is also a mechanism
 * for querying the set of known jobs in a given family.</li>
 * <li>Allows listeners to find out about progress on running jobs, and to find out
 * when jobs have changed states.</li>
 * <li>Provides a factory for creating lock objects.  Lock objects are smart monitors
 * that have strategies for avoiding deadlock.</li>
 * <li>Provide feedback to a client that is waiting for a given job or family of jobs
 * to complete.</li>
 * </ul>
 *
 * @see Job
 * @see ILock
 * @since 3.0
 * @noimplement This interface is not intended to be implemented by clients.
 */
public interface IJobManager {
    /**
     * A system property key indicating whether the job manager should create
     * job threads as daemon threads.  Set to <code>true</code> to force all worker
     * threads to be created as daemon threads. Set to <code>false</code> to force
     * all worker threads to be created as non-daemon threads.
     * @since 3.3
     */
    public static final String PROP_USE_DAEMON_THREADS = "eclipse.jobs.daemon"; //$NON-NLS-1$

    /**
     * Registers a job listener with the job manager.
     * Has no effect if an identical listener is already registered.
     *
     * @param listener the listener to be added
     * @see #removeJobChangeListener(IJobChangeListener)
     * @see IJobChangeListener
     */
    public void addJobChangeListener(IJobChangeListener listener);

    /**
     * Begins applying this rule in the calling thread.  If the rule conflicts with another
     * rule currently running in another thread, this method blocks until there are
     * no conflicting rules.  Calls to <tt>beginRule</tt> must eventually be followed
     * by a matching call to <tt>endRule</tt> in the same thread and with the identical
     * rule instance.
     * <p>
     * Rules can be nested only if the rule for the inner <tt>beginRule</tt>
     * is contained within the rule for the outer <tt>beginRule</tt>.  Rule containment
     * is tested with the API method <tt>ISchedulingRule.contains</tt>.  Also, begin/end
     * pairs must be strictly nested.  Only the rule that has most recently begun
     * can be ended at any given time.
     * <p>
     * A rule of <code>null</code> can be used, but will be ignored for scheduling
     * purposes.  The outermost non-null rule in the thread will be used for scheduling. A
     * <code>null</code> rule that is begun must still be ended.
     * <p>
     * If this method is called from within a job that has a scheduling rule, the
     * given rule must also be contained within the rule for the running job.
     * <p>
     * Note that <tt>endRule</tt> must be called even if <tt>beginRule</tt> fails.
     * The recommended usage is:
     * <pre>
     * final ISchedulingRule rule = ...;
     * try {
     *  manager.beginRule(rule, monitor);
     * } finally {
     *  manager.endRule(rule);
     * }
     * </pre>
     *
     * @param rule the rule to begin applying in this thread, or <code>null</code>
     * @param monitor a progress monitor, or <code>null</code> if progress
     *    reporting and cancellation are not desired
     * @throws IllegalArgumentException if the rule is not strictly nested within
     *  all other rules currently active for this thread
     * @throws OperationCanceledException if the supplied monitor reports cancelation
     *  before the rule becomes available
     * @see ISchedulingRule#contains(ISchedulingRule)
     */
    public void beginRule(ISchedulingRule rule, IProgressMonitor monitor);

    /**
     * Cancels all jobs in the given job family.  Jobs in the family that are currently waiting
     * will be removed from the queue.  Sleeping jobs will be discarded without having
     * a chance to wake up.  Currently executing jobs will be asked to cancel but there
     * is no guarantee that they will do so.
     *
     * @param family the job family to cancel, or <code>null</code> to cancel all jobs
     * @see Job#belongsTo(Object)
     */
    public void cancel(Object family);

    /**
     * Returns a progress monitor that can be used to provide
     * aggregated progress feedback on a set of running jobs. A user
     * interface will typically group all jobs in a progress group together,
     * providing progress feedback for individual jobs as well as aggregated
     * progress for the entire group.  Jobs in the group may be run sequentially,
     * in parallel, or some combination of the two.
     * <p>
     * Recommended usage (this snippet runs two jobs in sequence in a
     * single progress group):
     * <pre>
     *    Job parseJob, compileJob;
     *    IProgressMonitor pm = Platform.getJobManager().createProgressGroup();
     *    try {
     *       pm.beginTask("Building", 10);
     *       parseJob.setProgressGroup(pm, 5);
     *       parseJob.schedule();
     *       compileJob.setProgressGroup(pm, 5);
     *       compileJob.schedule();
     *       parseJob.join();
     *       compileJob.join();
     *    } finally {
     *       pm.done();
     *    }
     * </pre>
     *
     * @see Job#setProgressGroup(IProgressMonitor, int)
     * @see IProgressMonitor
     * @return a progress monitor
     */
    public IProgressMonitor createProgressGroup();

    /**
     * Returns the job that is currently running in this thread, or <code>null</code> if there
     * is no currently running job.
     *
     * @return the job or <code>null</code>
     */
    public Job currentJob();

    /**
     * Ends the application of a rule to the calling thread.  Calls to <tt>endRule</tt>
     * must be preceded by a matching call to <tt>beginRule</tt> in the same thread
     * with an identical rule instance.
     * <p>
     * Rules can be nested only if the rule for the inner <tt>beginRule</tt>
     * is contained within the rule for the outer <tt>beginRule</tt>.  Also, begin/end
     * pairs must be strictly nested.  Only the rule that has most recently begun
     * can be ended at any given time.
     *
     * @param rule the rule to end applying in this thread
     * @throws IllegalArgumentException if this method is called on a rule for which
     * there is no matching begin, or that does not match the most recent begin.
     * @see ISchedulingRule#contains(ISchedulingRule)
     */
    public void endRule(ISchedulingRule rule);

    /**
     * Returns all waiting, executing and sleeping jobs belonging
     * to the given family. If no jobs are found, an empty array is returned.
     *
     * @param family the job family to find, or <code>null</code> to find all jobs
     * @return the job array
     * @see Job#belongsTo(Object)
     */
    public Job[] find(Object family);

    /**
     * Returns whether the job manager is currently idle.  The job manager is
     * idle if no jobs are currently running or waiting to run.
     *
     * @return <code>true</code> if the job manager is idle, and
     * <code>false</code> otherwise
     * @since 3.1
     */
    public bool isIdle();

    /**
     * Returns whether the job manager is currently suspended.
     *
     * @return <code>true</code> if the job manager is suspended, and
     * <code>false</code> otherwise
     * @since 3.4
     * @see #suspend()
     * @see #resume()
     */
    public bool isSuspended();

    /**
     * Waits until all jobs of the given family are finished.  This method will block the
     * calling thread until all such jobs have finished executing, or until this thread is
     * interrupted.   If there are no jobs in
     * the family that are currently waiting, running, or sleeping, this method returns
     * immediately.  Feedback on how the join is progressing is provided to a  progress
     * monitor.
     * <p>
     * If this method is called while the job manager is suspended, only jobs
     * that are currently running will be joined; Once there are no jobs
     * in the family in the {@link Job#RUNNING} state, this method returns.
     * </p>
     * <p>
     * Note that there is a deadlock risk when using join.  If the calling thread owns
     * a lock or object monitor that the joined thread is waiting for, deadlock
     * will occur. This method can also result in starvation of the current thread if
     * another thread continues to add jobs of the given family, or if a
     * job in the given family reschedules itself in an infinite loop.
     * </p>
     *
     * @param family the job family to join, or <code>null</code> to join all jobs.
     * @param monitor Progress monitor for reporting progress on how the
     * wait is progressing, or <code>null</code> if no progress monitoring is required.
     * @exception InterruptedException if this thread is interrupted while waiting
     * @exception OperationCanceledException if the progress monitor is canceled while waiting
     * @see Job#belongsTo(Object)
     * @see #suspend()
     */
    public void join(Object family, IProgressMonitor monitor);

    /**
     * Creates a new lock object.  All lock objects supplied by the job manager
     * know about each other and will always avoid circular deadlock amongst
     * themselves.
     *
     * @return the new lock object
     */
    public ILock newLock();

    /**
     * Removes a job listener from the job manager.
     * Has no effect if an identical listener is not already registered.
     *
     * @param listener the listener to be removed
     * @see #addJobChangeListener(IJobChangeListener)
     * @see IJobChangeListener
     */
    public void removeJobChangeListener(IJobChangeListener listener);

    /**
     * Resumes execution of jobs after a previous <code>suspend</code>.  All
     * jobs that were sleeping or waiting prior to the suspension, or that were
     * scheduled while the job manager was suspended, will now be eligible
     * for execution.
     * <p>
     * Calling this method on a rule that is not suspended  has no effect.  If another
     * thread also owns the rule at the time this method is called, then the rule will
     * not be resumed until all threads have released the rule.
     *
     * @deprecated This method is not safe and should not be used.
     * Suspending a scheduling rule violates the thread safety
     * of clients that use scheduling rules as a mutual exclusion mechanism,
     * and can result in concurrency problems in all clients that use the suspended rule.
     * @see #suspend(ISchedulingRule, IProgressMonitor)
     */
    public void resume(ISchedulingRule rule);

    /**
     * Resumes execution of jobs after a previous <code>suspend</code>.  All
     * jobs that were sleeping or waiting prior to the suspension, or that were
     * scheduled while the job manager was suspended, will now be eligible
     * for execution.
     * <p>
     * Calling <code>resume</code> when the job manager is not suspended
     * has no effect.
     *
     * @see #suspend()
     * @see #isSuspended()
     */
    public void resume();

    /**
     * Provides a hook that is notified whenever a thread is about to wait on a lock,
     * or when a thread is about to release a lock.  This hook must only be set once.
     * <p>
     * This method is for internal use by the platform-related plug-ins.
     * Clients should not call this method.
     * </p>
     * @see LockListener
     */
    public void setLockListener(LockListener listener);

    /**
     * Registers a progress provider with the job manager.  If there was a
     * provider already registered, it is replaced.
     * <p>
     * This method is intended for use by the currently executing Eclipse application.
     * Plug-ins outside the currently running application should not call this method.
     * </p>
     *
     * @param provider the new provider, or <code>null</code> if no progress
     * is needed
     */
    public void setProgressProvider(ProgressProvider provider);

    /**
     * Suspends execution of all jobs.  Jobs that are already running
     * when this method is invoked will complete as usual, but all sleeping and
     * waiting jobs will not be executed until the job manager is resumed.
     * <p>
     * The job manager will remain suspended until a subsequent call to
     * <code>resume</code>.  Further calls to <code>suspend</code>
     * when the job manager is already suspended are ignored.
     * <p>
     * All attempts to join sleeping and waiting jobs while the job manager is
     * suspended will return immediately.
     * <p>
     * Note that this very powerful function should be used with extreme caution.
     * Suspending the job manager will prevent all jobs in the system from executing,
     * which may have adverse affects on components that are relying on
     * execution of jobs. The job manager should never be suspended without intent
     * to resume execution soon afterwards.
     *
     * @see #resume()
     * @see #join(Object, IProgressMonitor)
     * @see #isSuspended()
     */
    public void suspend();

    /**
     * Defers execution of all jobs with scheduling rules that conflict with the
     * given rule. The caller will be blocked until all currently executing jobs with
     * conflicting rules are completed.  Conflicting jobs that are sleeping or waiting at
     * the time this method is called will not be executed until the rule is resumed.
     * <p>
     * While a rule is suspended, all calls to <code>beginRule</code> and
     * <code>endRule</code> on a suspended rule will not block the caller.
     * The rule remains suspended until a subsequent call to
     * <code>resume(ISchedulingRule)</code> with the identical rule instance.
     * Further calls to <code>suspend</code> with an identical rule prior to calling
     * <code>resume</code> are ignored.
     * </p>
     * <p>
     * This method is long-running; progress and cancelation are provided by
     * the given progress monitor. In the case of cancelation, the rule will
     * not be suspended.
     * </p>
     * Note: this very powerful function should be used with extreme caution.
     * Suspending rules will prevent jobs in the system from executing, which may
     * have adverse effects on components that are relying on execution of jobs.
     * The job manager should never be suspended without intent to resume
     * execution soon afterwards. Deadlock will result if the thread responsible
     * for resuming the rule attempts to join a suspended job.
     *
     * @deprecated This method is not safe and should not be used.
     * Suspending a scheduling rule violates the thread safety
     * of clients that use scheduling rules as a mutual exclusion mechanism,
     * and can result in concurrency problems in all clients that use the suspended rule.
     * @param rule The scheduling rule to suspend. Must not be <code>null</code>.
     * @param monitor a progress monitor, or <code>null</code> if progress
     * reporting is not desired
     * @exception OperationCanceledException if the operation is canceled.
     * Cancelation can occur even if no progress monitor is provided.
     * @see #resume(ISchedulingRule)
     */
    public void suspend(ISchedulingRule rule, IProgressMonitor monitor);

    /**
     * Requests that all jobs in the given job family be suspended.  Jobs currently
     * waiting to be run will be removed from the queue and moved into the
     * <code>SLEEPING</code> state.  Jobs that have been put to sleep
     * will remain in that state until either resumed or canceled.  This method has
     * no effect on jobs that are not currently waiting to be run.
     * <p>
     * Sleeping jobs can be resumed using <code>wakeUp</code>.
     *
     * @param family the job family to sleep, or <code>null</code> to sleep all jobs.
     * @see Job#belongsTo(Object)
     */
    public void sleep(Object family);

    /**
     * Transfers ownership of a scheduling rule to another thread.  The identical
     * scheduling rule must currently be owned by the calling thread as a result of
     * a previous call to <code>beginRule</code>.  The destination thread must
     * not already own a scheduling rule.
     * <p>
     * Calling this method is equivalent to atomically calling <code>endRule</code>
     * in the calling thread followed by an immediate <code>beginRule</code> in
     * the destination thread.  The destination thread is responsible for subsequently
     * calling <code>endRule</code> when it is finished using the rule.
     * <p>
     * This method has no effect when the destination thread is the same as the
     * calling thread.
     *
     * @param rule The scheduling rule to transfer
     * @param destinationThread The new owner for the transferred rule.
     * @since 3.1
     */
    public void transferRule(ISchedulingRule rule, Thread destinationThread);

    /**
     * Resumes scheduling of all sleeping jobs in the given family.  This method
     * has no effect on jobs in the family that are not currently sleeping.
     *
     * @param family the job family to wake up, or <code>null</code> to wake up all jobs
     * @see Job#belongsTo(Object)
     */
    public void wakeUp(Object family);
}