Mercurial > projects > dwt-addons
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); }