comparison 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
comparison
equal deleted inserted replaced
121:c0304616ea23 122:9d0585bcb7aa
1 /*******************************************************************************
2 * Copyright (c) 2003, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/
13 module dwtx.core.runtime.jobs.IJobManager;
14
15 import dwt.dwthelper.utils;
16
17 import dwtx.core.runtime.IProgressMonitor;
18 import dwtx.core.runtime.OperationCanceledException;
19 import dwtx.core.runtime.jobs.IJobChangeListener;
20 import dwtx.core.runtime.jobs.ISchedulingRule;
21 import dwtx.core.runtime.jobs.Job;
22 import dwtx.core.runtime.jobs.ILock;
23 import dwtx.core.runtime.jobs.LockListener;
24
25 import dwtx.core.runtime.jobs.ProgressProvider;
26 import tango.core.Thread;
27
28 /**
29 * The job manager provides facilities for scheduling, querying, and maintaining jobs
30 * and locks. In particular, the job manager provides the following services:
31 * <ul>
32 * <li>Maintains a queue of jobs that are waiting to be run. Items can be added to
33 * the queue using the <code>schedule</code> method.</li>
34 * <li>Allows manipulation of groups of jobs called job families. Job families can
35 * be canceled, put to sleep, or woken up atomically. There is also a mechanism
36 * for querying the set of known jobs in a given family.</li>
37 * <li>Allows listeners to find out about progress on running jobs, and to find out
38 * when jobs have changed states.</li>
39 * <li>Provides a factory for creating lock objects. Lock objects are smart monitors
40 * that have strategies for avoiding deadlock.</li>
41 * <li>Provide feedback to a client that is waiting for a given job or family of jobs
42 * to complete.</li>
43 * </ul>
44 *
45 * @see Job
46 * @see ILock
47 * @since 3.0
48 * @noimplement This interface is not intended to be implemented by clients.
49 */
50 public interface IJobManager {
51 /**
52 * A system property key indicating whether the job manager should create
53 * job threads as daemon threads. Set to <code>true</code> to force all worker
54 * threads to be created as daemon threads. Set to <code>false</code> to force
55 * all worker threads to be created as non-daemon threads.
56 * @since 3.3
57 */
58 public static final String PROP_USE_DAEMON_THREADS = "eclipse.jobs.daemon"; //$NON-NLS-1$
59
60 /**
61 * Registers a job listener with the job manager.
62 * Has no effect if an identical listener is already registered.
63 *
64 * @param listener the listener to be added
65 * @see #removeJobChangeListener(IJobChangeListener)
66 * @see IJobChangeListener
67 */
68 public void addJobChangeListener(IJobChangeListener listener);
69
70 /**
71 * Begins applying this rule in the calling thread. If the rule conflicts with another
72 * rule currently running in another thread, this method blocks until there are
73 * no conflicting rules. Calls to <tt>beginRule</tt> must eventually be followed
74 * by a matching call to <tt>endRule</tt> in the same thread and with the identical
75 * rule instance.
76 * <p>
77 * Rules can be nested only if the rule for the inner <tt>beginRule</tt>
78 * is contained within the rule for the outer <tt>beginRule</tt>. Rule containment
79 * is tested with the API method <tt>ISchedulingRule.contains</tt>. Also, begin/end
80 * pairs must be strictly nested. Only the rule that has most recently begun
81 * can be ended at any given time.
82 * <p>
83 * A rule of <code>null</code> can be used, but will be ignored for scheduling
84 * purposes. The outermost non-null rule in the thread will be used for scheduling. A
85 * <code>null</code> rule that is begun must still be ended.
86 * <p>
87 * If this method is called from within a job that has a scheduling rule, the
88 * given rule must also be contained within the rule for the running job.
89 * <p>
90 * Note that <tt>endRule</tt> must be called even if <tt>beginRule</tt> fails.
91 * The recommended usage is:
92 * <pre>
93 * final ISchedulingRule rule = ...;
94 * try {
95 * manager.beginRule(rule, monitor);
96 * } finally {
97 * manager.endRule(rule);
98 * }
99 * </pre>
100 *
101 * @param rule the rule to begin applying in this thread, or <code>null</code>
102 * @param monitor a progress monitor, or <code>null</code> if progress
103 * reporting and cancellation are not desired
104 * @throws IllegalArgumentException if the rule is not strictly nested within
105 * all other rules currently active for this thread
106 * @throws OperationCanceledException if the supplied monitor reports cancelation
107 * before the rule becomes available
108 * @see ISchedulingRule#contains(ISchedulingRule)
109 */
110 public void beginRule(ISchedulingRule rule, IProgressMonitor monitor);
111
112 /**
113 * Cancels all jobs in the given job family. Jobs in the family that are currently waiting
114 * will be removed from the queue. Sleeping jobs will be discarded without having
115 * a chance to wake up. Currently executing jobs will be asked to cancel but there
116 * is no guarantee that they will do so.
117 *
118 * @param family the job family to cancel, or <code>null</code> to cancel all jobs
119 * @see Job#belongsTo(Object)
120 */
121 public void cancel(Object family);
122
123 /**
124 * Returns a progress monitor that can be used to provide
125 * aggregated progress feedback on a set of running jobs. A user
126 * interface will typically group all jobs in a progress group together,
127 * providing progress feedback for individual jobs as well as aggregated
128 * progress for the entire group. Jobs in the group may be run sequentially,
129 * in parallel, or some combination of the two.
130 * <p>
131 * Recommended usage (this snippet runs two jobs in sequence in a
132 * single progress group):
133 * <pre>
134 * Job parseJob, compileJob;
135 * IProgressMonitor pm = Platform.getJobManager().createProgressGroup();
136 * try {
137 * pm.beginTask("Building", 10);
138 * parseJob.setProgressGroup(pm, 5);
139 * parseJob.schedule();
140 * compileJob.setProgressGroup(pm, 5);
141 * compileJob.schedule();
142 * parseJob.join();
143 * compileJob.join();
144 * } finally {
145 * pm.done();
146 * }
147 * </pre>
148 *
149 * @see Job#setProgressGroup(IProgressMonitor, int)
150 * @see IProgressMonitor
151 * @return a progress monitor
152 */
153 public IProgressMonitor createProgressGroup();
154
155 /**
156 * Returns the job that is currently running in this thread, or <code>null</code> if there
157 * is no currently running job.
158 *
159 * @return the job or <code>null</code>
160 */
161 public Job currentJob();
162
163 /**
164 * Ends the application of a rule to the calling thread. Calls to <tt>endRule</tt>
165 * must be preceded by a matching call to <tt>beginRule</tt> in the same thread
166 * with an identical rule instance.
167 * <p>
168 * Rules can be nested only if the rule for the inner <tt>beginRule</tt>
169 * is contained within the rule for the outer <tt>beginRule</tt>. Also, begin/end
170 * pairs must be strictly nested. Only the rule that has most recently begun
171 * can be ended at any given time.
172 *
173 * @param rule the rule to end applying in this thread
174 * @throws IllegalArgumentException if this method is called on a rule for which
175 * there is no matching begin, or that does not match the most recent begin.
176 * @see ISchedulingRule#contains(ISchedulingRule)
177 */
178 public void endRule(ISchedulingRule rule);
179
180 /**
181 * Returns all waiting, executing and sleeping jobs belonging
182 * to the given family. If no jobs are found, an empty array is returned.
183 *
184 * @param family the job family to find, or <code>null</code> to find all jobs
185 * @return the job array
186 * @see Job#belongsTo(Object)
187 */
188 public Job[] find(Object family);
189
190 /**
191 * Returns whether the job manager is currently idle. The job manager is
192 * idle if no jobs are currently running or waiting to run.
193 *
194 * @return <code>true</code> if the job manager is idle, and
195 * <code>false</code> otherwise
196 * @since 3.1
197 */
198 public bool isIdle();
199
200 /**
201 * Returns whether the job manager is currently suspended.
202 *
203 * @return <code>true</code> if the job manager is suspended, and
204 * <code>false</code> otherwise
205 * @since 3.4
206 * @see #suspend()
207 * @see #resume()
208 */
209 public bool isSuspended();
210
211 /**
212 * Waits until all jobs of the given family are finished. This method will block the
213 * calling thread until all such jobs have finished executing, or until this thread is
214 * interrupted. If there are no jobs in
215 * the family that are currently waiting, running, or sleeping, this method returns
216 * immediately. Feedback on how the join is progressing is provided to a progress
217 * monitor.
218 * <p>
219 * If this method is called while the job manager is suspended, only jobs
220 * that are currently running will be joined; Once there are no jobs
221 * in the family in the {@link Job#RUNNING} state, this method returns.
222 * </p>
223 * <p>
224 * Note that there is a deadlock risk when using join. If the calling thread owns
225 * a lock or object monitor that the joined thread is waiting for, deadlock
226 * will occur. This method can also result in starvation of the current thread if
227 * another thread continues to add jobs of the given family, or if a
228 * job in the given family reschedules itself in an infinite loop.
229 * </p>
230 *
231 * @param family the job family to join, or <code>null</code> to join all jobs.
232 * @param monitor Progress monitor for reporting progress on how the
233 * wait is progressing, or <code>null</code> if no progress monitoring is required.
234 * @exception InterruptedException if this thread is interrupted while waiting
235 * @exception OperationCanceledException if the progress monitor is canceled while waiting
236 * @see Job#belongsTo(Object)
237 * @see #suspend()
238 */
239 public void join(Object family, IProgressMonitor monitor);
240
241 /**
242 * Creates a new lock object. All lock objects supplied by the job manager
243 * know about each other and will always avoid circular deadlock amongst
244 * themselves.
245 *
246 * @return the new lock object
247 */
248 public ILock newLock();
249
250 /**
251 * Removes a job listener from the job manager.
252 * Has no effect if an identical listener is not already registered.
253 *
254 * @param listener the listener to be removed
255 * @see #addJobChangeListener(IJobChangeListener)
256 * @see IJobChangeListener
257 */
258 public void removeJobChangeListener(IJobChangeListener listener);
259
260 /**
261 * Resumes execution of jobs after a previous <code>suspend</code>. All
262 * jobs that were sleeping or waiting prior to the suspension, or that were
263 * scheduled while the job manager was suspended, will now be eligible
264 * for execution.
265 * <p>
266 * Calling this method on a rule that is not suspended has no effect. If another
267 * thread also owns the rule at the time this method is called, then the rule will
268 * not be resumed until all threads have released the rule.
269 *
270 * @deprecated This method is not safe and should not be used.
271 * Suspending a scheduling rule violates the thread safety
272 * of clients that use scheduling rules as a mutual exclusion mechanism,
273 * and can result in concurrency problems in all clients that use the suspended rule.
274 * @see #suspend(ISchedulingRule, IProgressMonitor)
275 */
276 public void resume(ISchedulingRule rule);
277
278 /**
279 * Resumes execution of jobs after a previous <code>suspend</code>. All
280 * jobs that were sleeping or waiting prior to the suspension, or that were
281 * scheduled while the job manager was suspended, will now be eligible
282 * for execution.
283 * <p>
284 * Calling <code>resume</code> when the job manager is not suspended
285 * has no effect.
286 *
287 * @see #suspend()
288 * @see #isSuspended()
289 */
290 public void resume();
291
292 /**
293 * Provides a hook that is notified whenever a thread is about to wait on a lock,
294 * or when a thread is about to release a lock. This hook must only be set once.
295 * <p>
296 * This method is for internal use by the platform-related plug-ins.
297 * Clients should not call this method.
298 * </p>
299 * @see LockListener
300 */
301 public void setLockListener(LockListener listener);
302
303 /**
304 * Registers a progress provider with the job manager. If there was a
305 * provider already registered, it is replaced.
306 * <p>
307 * This method is intended for use by the currently executing Eclipse application.
308 * Plug-ins outside the currently running application should not call this method.
309 * </p>
310 *
311 * @param provider the new provider, or <code>null</code> if no progress
312 * is needed
313 */
314 public void setProgressProvider(ProgressProvider provider);
315
316 /**
317 * Suspends execution of all jobs. Jobs that are already running
318 * when this method is invoked will complete as usual, but all sleeping and
319 * waiting jobs will not be executed until the job manager is resumed.
320 * <p>
321 * The job manager will remain suspended until a subsequent call to
322 * <code>resume</code>. Further calls to <code>suspend</code>
323 * when the job manager is already suspended are ignored.
324 * <p>
325 * All attempts to join sleeping and waiting jobs while the job manager is
326 * suspended will return immediately.
327 * <p>
328 * Note that this very powerful function should be used with extreme caution.
329 * Suspending the job manager will prevent all jobs in the system from executing,
330 * which may have adverse affects on components that are relying on
331 * execution of jobs. The job manager should never be suspended without intent
332 * to resume execution soon afterwards.
333 *
334 * @see #resume()
335 * @see #join(Object, IProgressMonitor)
336 * @see #isSuspended()
337 */
338 public void suspend();
339
340 /**
341 * Defers execution of all jobs with scheduling rules that conflict with the
342 * given rule. The caller will be blocked until all currently executing jobs with
343 * conflicting rules are completed. Conflicting jobs that are sleeping or waiting at
344 * the time this method is called will not be executed until the rule is resumed.
345 * <p>
346 * While a rule is suspended, all calls to <code>beginRule</code> and
347 * <code>endRule</code> on a suspended rule will not block the caller.
348 * The rule remains suspended until a subsequent call to
349 * <code>resume(ISchedulingRule)</code> with the identical rule instance.
350 * Further calls to <code>suspend</code> with an identical rule prior to calling
351 * <code>resume</code> are ignored.
352 * </p>
353 * <p>
354 * This method is long-running; progress and cancelation are provided by
355 * the given progress monitor. In the case of cancelation, the rule will
356 * not be suspended.
357 * </p>
358 * Note: this very powerful function should be used with extreme caution.
359 * Suspending rules will prevent jobs in the system from executing, which may
360 * have adverse effects on components that are relying on execution of jobs.
361 * The job manager should never be suspended without intent to resume
362 * execution soon afterwards. Deadlock will result if the thread responsible
363 * for resuming the rule attempts to join a suspended job.
364 *
365 * @deprecated This method is not safe and should not be used.
366 * Suspending a scheduling rule violates the thread safety
367 * of clients that use scheduling rules as a mutual exclusion mechanism,
368 * and can result in concurrency problems in all clients that use the suspended rule.
369 * @param rule The scheduling rule to suspend. Must not be <code>null</code>.
370 * @param monitor a progress monitor, or <code>null</code> if progress
371 * reporting is not desired
372 * @exception OperationCanceledException if the operation is canceled.
373 * Cancelation can occur even if no progress monitor is provided.
374 * @see #resume(ISchedulingRule)
375 */
376 public void suspend(ISchedulingRule rule, IProgressMonitor monitor);
377
378 /**
379 * Requests that all jobs in the given job family be suspended. Jobs currently
380 * waiting to be run will be removed from the queue and moved into the
381 * <code>SLEEPING</code> state. Jobs that have been put to sleep
382 * will remain in that state until either resumed or canceled. This method has
383 * no effect on jobs that are not currently waiting to be run.
384 * <p>
385 * Sleeping jobs can be resumed using <code>wakeUp</code>.
386 *
387 * @param family the job family to sleep, or <code>null</code> to sleep all jobs.
388 * @see Job#belongsTo(Object)
389 */
390 public void sleep(Object family);
391
392 /**
393 * Transfers ownership of a scheduling rule to another thread. The identical
394 * scheduling rule must currently be owned by the calling thread as a result of
395 * a previous call to <code>beginRule</code>. The destination thread must
396 * not already own a scheduling rule.
397 * <p>
398 * Calling this method is equivalent to atomically calling <code>endRule</code>
399 * in the calling thread followed by an immediate <code>beginRule</code> in
400 * the destination thread. The destination thread is responsible for subsequently
401 * calling <code>endRule</code> when it is finished using the rule.
402 * <p>
403 * This method has no effect when the destination thread is the same as the
404 * calling thread.
405 *
406 * @param rule The scheduling rule to transfer
407 * @param destinationThread The new owner for the transferred rule.
408 * @since 3.1
409 */
410 public void transferRule(ISchedulingRule rule, Thread destinationThread);
411
412 /**
413 * Resumes scheduling of all sleeping jobs in the given family. This method
414 * has no effect on jobs in the family that are not currently sleeping.
415 *
416 * @param family the job family to wake up, or <code>null</code> to wake up all jobs
417 * @see Job#belongsTo(Object)
418 */
419 public void wakeUp(Object family);
420 }