annotate dwtx/core/internal/jobs/ImplicitJobs.d @ 167:862b05e0334a

Add a wrapper for Thread
author Frank Benoit <benoit@tionex.de>
date Tue, 09 Sep 2008 15:59:16 +0200
parents 9d0585bcb7aa
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
1 /*******************************************************************************
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
2 * Copyright (c) 2003, 2006 IBM Corporation and others.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
3 * All rights reserved. This program and the accompanying materials
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
4 * are made available under the terms of the Eclipse Public License v1.0
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
5 * which accompanies this distribution, and is available at
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
6 * http://www.eclipse.org/legal/epl-v10.html
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
7 *
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
8 * Contributors:
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
9 * IBM - Initial API and implementation
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
10 * Port to the D programming language:
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
11 * Frank Benoit <benoit@tionex.de>
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
12 *******************************************************************************/
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
13 module dwtx.core.internal.jobs.ImplicitJobs;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
14
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
15 import tango.text.convert.Format;
167
862b05e0334a Add a wrapper for Thread
Frank Benoit <benoit@tionex.de>
parents: 122
diff changeset
16 import dwtx.dwtxhelper.JThread;
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
17 import tango.io.Stdout;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
18 import dwt.dwthelper.utils;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
19 import dwtx.dwtxhelper.Collection;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
20
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
21 import dwtx.core.internal.runtime.RuntimeLog;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
22 import dwtx.core.runtime.Assert;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
23 import dwtx.core.runtime.IProgressMonitor;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
24 import dwtx.core.runtime.IStatus;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
25 import dwtx.core.runtime.Status;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
26 import dwtx.core.runtime.jobs.ISchedulingRule;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
27 import dwtx.core.runtime.jobs.Job;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
28
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
29 import dwtx.core.internal.jobs.JobManager;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
30 import dwtx.core.internal.jobs.ThreadJob;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
31 import dwtx.core.internal.jobs.InternalJob;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
32
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
33 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
34 * Implicit jobs are jobs that are running by virtue of a JobManager.begin/end
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
35 * pair. They act like normal jobs, except they are tied to an arbitrary thread
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
36 * of the client's choosing, and they can be nested.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
37 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
38 class ImplicitJobs {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
39 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
40 * Cached unused instance that can be reused
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
41 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
42 private ThreadJob jobCache = null;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
43 protected JobManager manager;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
44
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
45 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
46 * Set of suspended scheduling rules.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
47 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
48 private const Set suspendedRules;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
49
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
50 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
51 * Maps (Thread->ThreadJob), threads to the currently running job for that
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
52 * thread.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
53 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
54 private final Map threadJobs;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
55
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
56 this(JobManager manager) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
57 this.manager = manager;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
58 suspendedRules = new HashSet(20);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
59 threadJobs = new HashMap(20);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
60 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
61
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
62 /* (Non-javadoc)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
63 * @see IJobManager#beginRule
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
64 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
65 void begin(ISchedulingRule rule, IProgressMonitor monitor, bool suspend) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
66 if (JobManager.DEBUG_BEGIN_END)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
67 JobManager.debug_(Format("Begin rule: {}", rule)); //$NON-NLS-1$
167
862b05e0334a Add a wrapper for Thread
Frank Benoit <benoit@tionex.de>
parents: 122
diff changeset
68 final JThread getThis = JThread.currentThread();
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
69 ThreadJob threadJob;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
70 synchronized (this) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
71 threadJob = cast(ThreadJob) threadJobs.get(getThis);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
72 if (threadJob !is null) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
73 //nested rule, just push on stack and return
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
74 threadJob.push(rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
75 return;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
76 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
77 //no need to schedule a thread job for a null rule
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
78 if (rule is null)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
79 return;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
80 //create a thread job for this thread, use the rule from the real job if it has one
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
81 Job realJob = manager.currentJob();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
82 if (realJob !is null && realJob.getRule() !is null)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
83 threadJob = newThreadJob(realJob.getRule());
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
84 else {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
85 threadJob = newThreadJob(rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
86 threadJob.acquireRule = true;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
87 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
88 //don't acquire rule if it is a suspended rule
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
89 if (isSuspended(rule))
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
90 threadJob.acquireRule = false;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
91 //indicate if it is a system job to ensure isBlocking works correctly
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
92 threadJob.setRealJob(realJob);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
93 threadJob.setThread(getThis);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
94 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
95 try {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
96 threadJob.push(rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
97 //join the thread job outside sync block
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
98 if (threadJob.acquireRule) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
99 //no need to re-acquire any locks because the thread did not wait to get this lock
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
100 if (manager.runNow_package(threadJob))
167
862b05e0334a Add a wrapper for Thread
Frank Benoit <benoit@tionex.de>
parents: 122
diff changeset
101 manager.getLockManager().addLockThread(JThread.currentThread(), rule);
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
102 else
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
103 threadJob = threadJob.joinRun(monitor);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
104 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
105 } finally {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
106 //remember this thread job - only do this
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
107 //after the rule is acquired because it is ok for this thread to acquire
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
108 //and release other rules while waiting.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
109 synchronized (this) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
110 threadJobs.put(getThis, threadJob);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
111 if (suspend)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
112 suspendedRules.add(cast(Object)rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
113 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
114 if (threadJob.isBlocked) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
115 threadJob.isBlocked = false;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
116 manager.reportUnblocked(monitor);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
117 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
118 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
119 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
120
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
121 /* (Non-javadoc)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
122 * @see IJobManager#endRule
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
123 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
124 synchronized void end(ISchedulingRule rule, bool resume) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
125 if (JobManager.DEBUG_BEGIN_END)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
126 JobManager.debug_(Format("End rule: {}", rule)); //$NON-NLS-1$
167
862b05e0334a Add a wrapper for Thread
Frank Benoit <benoit@tionex.de>
parents: 122
diff changeset
127 ThreadJob threadJob = cast(ThreadJob) threadJobs.get(JThread.currentThread());
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
128 if (threadJob is null)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
129 Assert.isLegal(rule is null, Format("endRule without matching beginRule: {}", rule)); //$NON-NLS-1$
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
130 else if (threadJob.pop(rule)) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
131 endThreadJob(threadJob, resume);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
132 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
133 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
134
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
135 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
136 * Called when a worker thread has finished running a job. At this
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
137 * point, the worker thread must not own any scheduling rules
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
138 * @param lastJob The last job to run in this thread
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
139 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
140 void endJob(InternalJob lastJob) {
167
862b05e0334a Add a wrapper for Thread
Frank Benoit <benoit@tionex.de>
parents: 122
diff changeset
141 final JThread getThis = JThread.currentThread();
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
142 IStatus error;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
143 synchronized (this) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
144 ThreadJob threadJob = cast(ThreadJob) threadJobs.get(getThis);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
145 if (threadJob is null) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
146 if (lastJob.getRule() !is null)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
147 notifyWaitingThreadJobs();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
148 return;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
149 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
150 String msg = Format("Worker thread ended job: {}, but still holds rule: {}", lastJob, threadJob ); //$NON-NLS-1$ //$NON-NLS-2$
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
151 error = new Status(IStatus.ERROR, JobManager.PI_JOBS, 1, msg, null);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
152 //end the thread job
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
153 endThreadJob(threadJob, false);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
154 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
155 try {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
156 RuntimeLog.log(error);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
157 } catch (RuntimeException e) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
158 //failed to log, so print to console instead
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
159 Stderr.formatln("{}", error.getMessage());
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
160 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
161 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
162
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
163 private void endThreadJob(ThreadJob threadJob, bool resume) {
167
862b05e0334a Add a wrapper for Thread
Frank Benoit <benoit@tionex.de>
parents: 122
diff changeset
164 JThread getThis = JThread.currentThread();
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
165 //clean up when last rule scope exits
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
166 threadJobs.remove(getThis);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
167 ISchedulingRule rule = threadJob.getRule();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
168 if (resume && rule !is null)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
169 suspendedRules.remove(cast(Object)rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
170 //if this job had a rule, then we are essentially releasing a lock
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
171 //note it is safe to do this even if the acquire was aborted
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
172 if (threadJob.acquireRule) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
173 manager.getLockManager().removeLockThread(getThis, rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
174 notifyWaitingThreadJobs();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
175 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
176 //if the job was started, we need to notify job manager to end it
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
177 if (threadJob.isRunning())
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
178 manager.endJob_package(threadJob, Status.OK_STATUS, false);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
179 recycle(threadJob);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
180 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
181
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
182 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
183 * Returns true if this rule has been suspended, and false otherwise.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
184 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
185 private bool isSuspended(ISchedulingRule rule) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
186 if (suspendedRules.size() is 0)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
187 return false;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
188 for (Iterator it = suspendedRules.iterator(); it.hasNext();)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
189 if ((cast(ISchedulingRule) it.next()).contains(rule))
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
190 return true;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
191 return false;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
192 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
193
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
194 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
195 * Returns a new or reused ThreadJob instance.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
196 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
197 private ThreadJob newThreadJob(ISchedulingRule rule) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
198 if (jobCache !is null) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
199 ThreadJob job = jobCache;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
200 job.setRule(rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
201 job.acquireRule = job.isRunning_ = false;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
202 job.realJob = null;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
203 jobCache = null;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
204 return job;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
205 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
206 return new ThreadJob(manager, rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
207 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
208
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
209 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
210 * A job has just finished that was holding a scheduling rule, and the
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
211 * scheduling rule is now free. Wake any blocked thread jobs so they can
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
212 * compete for the newly freed lock
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
213 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
214 private void notifyWaitingThreadJobs() {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
215 synchronized (ThreadJob.mutex) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
216 ThreadJob.condition.notifyAll();
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
217 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
218 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
219
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
220 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
221 * Indicates that a thread job is no longer in use and can be reused.
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
222 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
223 private void recycle(ThreadJob job) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
224 if (jobCache is null && job.recycle())
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
225 jobCache = job;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
226 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
227
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
228 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
229 * Implements IJobManager#resume(ISchedulingRule)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
230 * @param rule
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
231 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
232 void resume(ISchedulingRule rule) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
233 //resume happens as a consequence of freeing the last rule in the stack
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
234 end(rule, true);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
235 if (JobManager.DEBUG_BEGIN_END)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
236 JobManager.debug_(Format("Resume rule: {}", rule)); //$NON-NLS-1$
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
237 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
238
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
239 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
240 * Implements IJobManager#suspend(ISchedulingRule, IProgressMonitor)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
241 * @param rule
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
242 * @param monitor
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
243 */
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
244 void suspend(ISchedulingRule rule, IProgressMonitor monitor) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
245 if (JobManager.DEBUG_BEGIN_END)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
246 JobManager.debug_(Format("Suspend rule: {}", rule)); //$NON-NLS-1$
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
247 //the suspend job will be remembered once the rule is acquired
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
248 begin(rule, monitor, true);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
249 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
250
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
251 /**
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
252 * Implements IJobManager#transferRule(ISchedulingRule, Thread)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
253 */
167
862b05e0334a Add a wrapper for Thread
Frank Benoit <benoit@tionex.de>
parents: 122
diff changeset
254 synchronized void transfer(ISchedulingRule rule, JThread destinationThread) {
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
255 //nothing to do for null
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
256 if (rule is null)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
257 return;
167
862b05e0334a Add a wrapper for Thread
Frank Benoit <benoit@tionex.de>
parents: 122
diff changeset
258 JThread getThis = JThread.currentThread();
122
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
259 //nothing to do if transferring to the same thread
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
260 if (getThis is destinationThread)
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
261 return;
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
262 //ensure destination thread doesn't already have a rule
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
263 ThreadJob job = cast(ThreadJob) threadJobs.get(destinationThread);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
264 Assert.isLegal(job is null);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
265 //ensure calling thread owns the job being transferred
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
266 job = cast(ThreadJob) threadJobs.get(getThis);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
267 Assert.isNotNull(job);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
268 Assert.isLegal(job.getRule() is rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
269 //transfer the thread job without ending it
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
270 job.setThread(destinationThread);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
271 threadJobs.remove(getThis);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
272 threadJobs.put(destinationThread, job);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
273 //transfer lock
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
274 if (job.acquireRule) {
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
275 manager.getLockManager().removeLockThread(getThis, rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
276 manager.getLockManager().addLockThread(destinationThread, rule);
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
277 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
278 }
9d0585bcb7aa Add core.jobs package
Frank Benoit <benoit@tionex.de>
parents:
diff changeset
279 }