1 11 package org.eclipse.core.internal.jobs; 12 13 import java.util.*; 14 import org.eclipse.core.internal.runtime.RuntimeLog; 15 import org.eclipse.core.runtime.*; 16 import org.eclipse.core.runtime.jobs.ISchedulingRule; 17 import org.eclipse.core.runtime.jobs.Job; 18 19 24 class ImplicitJobs { 25 28 private ThreadJob jobCache = null; 29 protected JobManager manager; 30 31 34 private final Set suspendedRules = new HashSet(20); 35 36 40 private final Map threadJobs = new HashMap(20); 41 42 ImplicitJobs(JobManager manager) { 43 this.manager = manager; 44 } 45 46 49 void begin(ISchedulingRule rule, IProgressMonitor monitor, boolean suspend) { 50 if (JobManager.DEBUG_BEGIN_END) 51 JobManager.debug("Begin rule: " + rule); final Thread currentThread = Thread.currentThread(); 53 ThreadJob threadJob; 54 synchronized (this) { 55 threadJob = (ThreadJob) threadJobs.get(currentThread); 56 if (threadJob != null) { 57 threadJob.push(rule); 59 return; 60 } 61 if (rule == null) 63 return; 64 Job realJob = manager.currentJob(); 66 if (realJob != null && realJob.getRule() != null) 67 threadJob = newThreadJob(realJob.getRule()); 68 else { 69 threadJob = newThreadJob(rule); 70 threadJob.acquireRule = true; 71 } 72 if (isSuspended(rule)) 74 threadJob.acquireRule = false; 75 threadJob.setRealJob(realJob); 77 threadJob.setThread(currentThread); 78 } 79 try { 80 threadJob.push(rule); 81 if (threadJob.acquireRule) { 83 if (manager.runNow(threadJob)) 85 manager.getLockManager().addLockThread(Thread.currentThread(), rule); 86 else 87 threadJob = threadJob.joinRun(monitor); 88 } 89 } finally { 90 synchronized (this) { 94 threadJobs.put(currentThread, threadJob); 95 if (suspend) 96 suspendedRules.add(rule); 97 } 98 if (threadJob.isBlocked) { 99 threadJob.isBlocked = false; 100 manager.reportUnblocked(monitor); 101 } 102 } 103 } 104 105 108 synchronized void end(ISchedulingRule rule, boolean resume) { 109 if (JobManager.DEBUG_BEGIN_END) 110 JobManager.debug("End rule: " + rule); ThreadJob threadJob = (ThreadJob) threadJobs.get(Thread.currentThread()); 112 if (threadJob == null) 113 Assert.isLegal(rule == null, "endRule without matching beginRule: " + rule); else if (threadJob.pop(rule)) { 115 endThreadJob(threadJob, resume); 116 } 117 } 118 119 124 void endJob(InternalJob lastJob) { 125 final Thread currentThread = Thread.currentThread(); 126 IStatus error; 127 synchronized (this) { 128 ThreadJob threadJob = (ThreadJob) threadJobs.get(currentThread); 129 if (threadJob == null) { 130 if (lastJob.getRule() != null) 131 notifyWaitingThreadJobs(); 132 return; 133 } 134 String msg = "Worker thread ended job: " + lastJob + ", but still holds rule: " + threadJob; error = new Status(IStatus.ERROR, JobManager.PI_JOBS, 1, msg, null); 136 endThreadJob(threadJob, false); 138 } 139 try { 140 RuntimeLog.log(error); 141 } catch (RuntimeException e) { 142 System.err.println(error.getMessage()); 144 } 145 } 146 147 private void endThreadJob(ThreadJob threadJob, boolean resume) { 148 Thread currentThread = Thread.currentThread(); 149 threadJobs.remove(currentThread); 151 ISchedulingRule rule = threadJob.getRule(); 152 if (resume && rule != null) 153 suspendedRules.remove(rule); 154 if (threadJob.acquireRule) { 157 manager.getLockManager().removeLockThread(currentThread, rule); 158 notifyWaitingThreadJobs(); 159 } 160 if (threadJob.isRunning()) 162 manager.endJob(threadJob, Status.OK_STATUS, false); 163 recycle(threadJob); 164 } 165 166 169 private boolean isSuspended(ISchedulingRule rule) { 170 if (suspendedRules.size() == 0) 171 return false; 172 for (Iterator it = suspendedRules.iterator(); it.hasNext();) 173 if (((ISchedulingRule) it.next()).contains(rule)) 174 return true; 175 return false; 176 } 177 178 181 private ThreadJob newThreadJob(ISchedulingRule rule) { 182 if (jobCache != null) { 183 ThreadJob job = jobCache; 184 job.setRule(rule); 185 job.acquireRule = job.isRunning = false; 186 job.realJob = null; 187 jobCache = null; 188 return job; 189 } 190 return new ThreadJob(manager, rule); 191 } 192 193 198 private void notifyWaitingThreadJobs() { 199 synchronized (ThreadJob.notifier) { 200 ThreadJob.notifier.notifyAll(); 201 } 202 } 203 204 207 private void recycle(ThreadJob job) { 208 if (jobCache == null && job.recycle()) 209 jobCache = job; 210 } 211 212 216 void resume(ISchedulingRule rule) { 217 end(rule, true); 219 if (JobManager.DEBUG_BEGIN_END) 220 JobManager.debug("Resume rule: " + rule); } 222 223 228 void suspend(ISchedulingRule rule, IProgressMonitor monitor) { 229 if (JobManager.DEBUG_BEGIN_END) 230 JobManager.debug("Suspend rule: " + rule); begin(rule, monitor, true); 233 } 234 235 238 synchronized void transfer(ISchedulingRule rule, Thread destinationThread) { 239 if (rule == null) 241 return; 242 final Thread currentThread = Thread.currentThread(); 243 if (currentThread == destinationThread) 245 return; 246 ThreadJob job = (ThreadJob) threadJobs.get(destinationThread); 248 Assert.isLegal(job == null); 249 job = (ThreadJob) threadJobs.get(currentThread); 251 Assert.isNotNull(job); 252 Assert.isLegal(job.getRule() == rule); 253 job.setThread(destinationThread); 255 threadJobs.remove(currentThread); 256 threadJobs.put(destinationThread, job); 257 if (job.acquireRule) { 259 manager.getLockManager().removeLockThread(currentThread, rule); 260 manager.getLockManager().addLockThread(destinationThread, rule); 261 } 262 } 263 } 264 | Popular Tags |