122
|
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;
|
167
|
26 import dwtx.dwtxhelper.JThread;
|
122
|
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 */
|
167
|
410 public void transferRule(ISchedulingRule rule, JThread destinationThread);
|
122
|
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 }
|