/** * Returns a new or reused ThreadJob instance. */ private ThreadJob newThreadJob(ISchedulingRule rule) { if (jobCache != null) { ThreadJob job = jobCache; job.setRule(rule); job.acquireRule = job.isRunning = false; job.realJob = null; jobCache = null; return job; } return new ThreadJob(rule); }
/** * Pops a rule. Returns true if it was the last rule for this thread * job, and false otherwise. * @GuardedBy("JobManager.implicitJobs") */ boolean pop(ISchedulingRule rule) { if (top < 0 || ruleStack[top] != rule) illegalPop(rule); ruleStack[top--] = null; return top < 0; }
/** * Indicates that a thread job is no longer in use and can be reused. * @GuardedBy("this") */ private void recycle(ThreadJob job) { if (jobCache == null && job.recycle()) jobCache = job; }
boolean waiting = false; try { waitStart(threadJob, monitor, blockingJob); manager.implicitJobs.addWaiting(threadJob); waiting = true; if (isCanceled(monitor)) result.push(threadJob.getRule()); result.isBlocked = threadJob.isBlocked; manager.getLockManager().addLockWaitThread(currentThread, threadJob.getRule()); synchronized (blockingJob.jobStateLock) { try { manager.getLockManager().removeLockWaitThread(currentThread, threadJob.getRule()); Thread.currentThread().interrupt(); waitEnd(threadJob, threadJob == result, monitor); if (threadJob == result) { if (waiting)
if (threadJob != null) { threadJob.push(rule); return; threadJob.acquireRule = false; threadJob.setRealJob(realJob); threadJob.setThread(currentThread); threadJob.push(rule); manager.getLockManager().addLockThread(Thread.currentThread(), rule); else threadJob = ThreadJob.joinRun(threadJob, monitor);
if (likeThreadJob.getRule() != null) { getLockManager().removeLockThread(currentThread, likeThreadJob.getRule()); threadJob.setRealJob((Job) job); ThreadJob.joinRun(threadJob, nonCanceling); ThreadJob.joinRun(likeThreadJob, nonCanceling); synchronized (lock) { changeState(job, Job.RUNNING); if (unblocked instanceof ThreadJob && ((ThreadJob) unblocked).isResumingAfterYield()) {
/** * Reports that this thread was blocked, but is no longer blocked and is able * to proceed. * @param monitor The monitor to report unblocking to. */ static private void waitEnd(ThreadJob threadJob, boolean updateLockManager, IProgressMonitor monitor) { if (updateLockManager) { final LockManager lockManager = manager.getLockManager(); final Thread currentThread = Thread.currentThread(); if (threadJob.isRunning()) { lockManager.addLockThread(currentThread, threadJob.getRule()); //need to re-acquire any locks that were suspended while this thread was blocked on the rule lockManager.resumeSuspendedLocks(currentThread); } else { //tell lock manager that this thread gave up waiting lockManager.removeLockWaitThread(currentThread, threadJob.getRule()); } } if (threadJob.isBlocked) { threadJob.isBlocked = false; manager.reportUnblocked(monitor); } }
if (threadJob != null) { threadJob.push(rule); return; threadJob.acquireRule = false; threadJob.setRealJob(realJob); threadJob.setThread(currentThread); threadJob.push(rule); manager.getLockManager().addLockThread(Thread.currentThread(), rule); else threadJob = threadJob.joinRun(monitor);
/** * Adds a new scheduling rule to the stack of rules for this thread. Throws * a runtime exception if the new rule is not compatible with the base * scheduling rule for this thread. * @GuardedBy("JobManager.implicitJobs") */ void push(final ISchedulingRule rule) { final ISchedulingRule baseRule = getRule(); if (++top >= ruleStack.length) { ISchedulingRule[] newStack = new ISchedulingRule[ruleStack.length * 2]; System.arraycopy(ruleStack, 0, newStack, 0, ruleStack.length); ruleStack = newStack; } ruleStack[top] = rule; if (JobManager.DEBUG_BEGIN_END) lastPush = (RuntimeException) new RuntimeException().fillInStackTrace(); //check for containment last because we don't want to fail again on endRule if (baseRule != null && rule != null && !baseRule.contains(rule)) illegalPush(rule, baseRule); }
if (isCanceled(monitor)) throw new OperationCanceledException(); return waitForRun(threadJob, monitor, blockingJob, blocker); } finally { manager.getLockManager().aboutToRelease();
synchronized void end(ISchedulingRule rule, boolean resume) { if (JobManager.DEBUG_BEGIN_END) JobManager.debug("End rule: " + rule); //$NON-NLS-1$ ThreadJob threadJob = threadJobs.get(Thread.currentThread()); if (threadJob == null) Assert.isLegal(rule == null, "endRule without matching beginRule: " + rule); //$NON-NLS-1$ else if (threadJob.pop(rule)) { endThreadJob(threadJob, resume); } }
private void endThreadJob(ThreadJob threadJob, boolean resume) { Thread currentThread = Thread.currentThread(); //clean up when last rule scope exits threadJobs.remove(currentThread); ISchedulingRule rule = threadJob.getRule(); if (resume && rule != null) suspendedRules.remove(rule); //if this job had a rule, then we are essentially releasing a lock //note it is safe to do this even if the acquire was aborted if (threadJob.acquireRule) { manager.getLockManager().removeLockThread(currentThread, rule); notifyWaitingThreadJobs(); } //if the job was started, we need to notify job manager to end it if (threadJob.isRunning()) manager.endJob(threadJob, Status.OK_STATUS, false); recycle(threadJob); }
/** * Adds a new scheduling rule to the stack of rules for this thread. Throws * a runtime exception if the new rule is not compatible with the base * scheduling rule for this thread. */ void push(final ISchedulingRule rule) { final ISchedulingRule baseRule = getRule(); if (++top >= ruleStack.length) { ISchedulingRule[] newStack = new ISchedulingRule[ruleStack.length * 2]; System.arraycopy(ruleStack, 0, newStack, 0, ruleStack.length); ruleStack = newStack; } ruleStack[top] = rule; if (JobManager.DEBUG_BEGIN_END) lastPush = (RuntimeException) new RuntimeException().fillInStackTrace(); //check for containment last because we don't want to fail again on endRule if (baseRule != null && rule != null && !baseRule.contains(rule)) illegalPush(rule, baseRule); }
boolean waiting = false; try { waitStart(threadJob, monitor, blockingJob); manager.implicitJobs.addWaiting(threadJob); waiting = true; if (isCanceled(monitor)) result.push(threadJob.getRule()); result.isBlocked = threadJob.isBlocked; manager.getLockManager().addLockWaitThread(currentThread, threadJob.getRule()); synchronized (blockingJob.jobStateLock) { try { manager.getLockManager().removeLockWaitThread(currentThread, threadJob.getRule()); Thread.currentThread().interrupt(); waitEnd(threadJob, threadJob == result, monitor); if (threadJob == result) { if (waiting)
if (threadJob != null) { threadJob.push(rule); return; threadJob.acquireRule = false; threadJob.setRealJob(realJob); threadJob.setThread(currentThread); threadJob.push(rule); manager.getLockManager().addLockThread(Thread.currentThread(), rule); else threadJob = ThreadJob.joinRun(threadJob, monitor);
if (likeThreadJob.getRule() != null) { getLockManager().removeLockThread(currentThread, likeThreadJob.getRule()); threadJob.setRealJob((Job) job); ThreadJob.joinRun(threadJob, nonCanceling); ThreadJob.joinRun(likeThreadJob, nonCanceling); synchronized (lock) { changeState(job, Job.RUNNING); if (unblocked instanceof ThreadJob && ((ThreadJob) unblocked).isResumingAfterYield()) {
/** * Reports that this thread was blocked, but is no longer blocked and is able * to proceed. * @param monitor The monitor to report unblocking to. */ static private void waitEnd(ThreadJob threadJob, boolean updateLockManager, IProgressMonitor monitor) { if (updateLockManager) { final LockManager lockManager = manager.getLockManager(); final Thread currentThread = Thread.currentThread(); if (threadJob.isRunning()) { lockManager.addLockThread(currentThread, threadJob.getRule()); //need to re-acquire any locks that were suspended while this thread was blocked on the rule lockManager.resumeSuspendedLocks(currentThread); } else { //tell lock manager that this thread gave up waiting lockManager.removeLockWaitThread(currentThread, threadJob.getRule()); } } if (threadJob.isBlocked) { threadJob.isBlocked = false; manager.reportUnblocked(monitor); } }
/** * Adds a new scheduling rule to the stack of rules for this thread. Throws * a runtime exception if the new rule is not compatible with the base * scheduling rule for this thread. * @GuardedBy("JobManager.implicitJobs") */ void push(final ISchedulingRule rule) { final ISchedulingRule baseRule = getRule(); if (++top >= ruleStack.length) { ISchedulingRule[] newStack = new ISchedulingRule[ruleStack.length * 2]; System.arraycopy(ruleStack, 0, newStack, 0, ruleStack.length); ruleStack = newStack; } ruleStack[top] = rule; if (JobManager.DEBUG_BEGIN_END) lastPush = (RuntimeException) new RuntimeException().fillInStackTrace(); //check for containment last because we don't want to fail again on endRule if (baseRule != null && rule != null && !(baseRule.contains(rule) && baseRule.isConflicting(rule))) illegalPush(rule, baseRule); }
if (isCanceled(monitor)) throw new OperationCanceledException(); return waitForRun(threadJob, monitor, blockingJob, blocker); } finally { manager.getLockManager().aboutToRelease();
synchronized void end(ISchedulingRule rule, boolean resume) { if (JobManager.DEBUG_BEGIN_END) JobManager.debug("End rule: " + rule); //$NON-NLS-1$ ThreadJob threadJob = (ThreadJob) threadJobs.get(Thread.currentThread()); if (threadJob == null) Assert.isLegal(rule == null, "endRule without matching beginRule: " + rule); //$NON-NLS-1$ else if (threadJob.pop(rule)) { endThreadJob(threadJob, resume); } }