/** * Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package org.python.pydev.core.concurrency; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.jobs.Job; import org.python.pydev.core.log.Log; /** * Helper class to ensure that only 1 job will be running. * * Clients should call addJob(job) to schedule the job and the job itself must call removeJob(job) * when finished (on a try..finally). */ public class SingleJobRunningPool { /** * Lock to access runningJobs. */ private static Object jobsLock = new Object(); /** * The 1st job in this list is always running! */ private List<Job> runningJobs = new ArrayList<Job>(); /** * Adds a job. Schedules it to be run if it's the 1st added job. * * Clients are responsible for calling removeJob(job) when the job finishes. */ public void addJob(Job job) { synchronized (jobsLock) { runningJobs.add(job); if (runningJobs.size() == 1) { //no other will run it when finished! job.schedule(100); } } } /** * Removes the job from the running jobs and starts a new one (if one is available). */ public void removeJob(Job job) { synchronized (jobsLock) { if (runningJobs.size() == 0) { Log.log("Something bad happened: trying to remove a job when no running job is available!! This should never happen."); return; } Job removed = runningJobs.remove(0); if (removed != job) { Log.log("Something bad happened: the removed one should always be in position 0!!! This should never happen."); //We got into a really bad state, just start over (and just to be explicit, //this is a programming error and we're just trying to keep things running //by going to a known state). runningJobs.clear(); return; } //Start the next job (if one is available). if (runningJobs.size() > 0) { runningJobs.get(0).schedule(100); } } } }