Mercurial > projects > dwt-addons
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/core/runtime/jobs/IJobManager.d Tue Aug 12 02:34:21 2008 +0200 @@ -0,0 +1,420 @@ +/******************************************************************************* + * 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); +}