/*******************************************************************************
 *  Copyright (c) 2003, 2012 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     IBM - Initial API and implementation
 *******************************************************************************/
package org.eclipse.core.internal.jobs;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;

/**
 * Maintains a pool of worker threads. Threads are constructed lazily as
 * required, and are eventually discarded if not in use for awhile. This class
 * maintains the thread creation/destruction policies for the job manager.
 *
 * Implementation note: all the data structures of this class are protected
 * by the instance's object monitor.  To avoid deadlock with third party code,
 * this lock is never held when calling methods outside this class that may in
 * turn use locks.
 */
class WorkerPool {
	/**
	 * Threads not used by their best before timestamp are destroyed.
	 */
	private static final int BEST_BEFORE = 60000;
	/**
	 * There will always be at least MIN_THREADS workers in the pool.
	 */
	private static final int MIN_THREADS = 1;
	/**
	 * Use the busy thread count to avoid starting new threads when a living
	 * thread is just doing house cleaning (notifying listeners, etc).
	 */
	private int busyThreads = 0;

	/**
	 * The default context class loader to use when creating worker threads.
	 */
	protected final ClassLoader defaultContextLoader;

	/**
	 * Records whether new worker threads should be daemon threads.
	 */
	private boolean isDaemon = false;

	private JobManager manager;
	/**
	 * The number of workers in the threads array
	 */
	private int numThreads = 0;
	/**
	 * The number of threads that are currently sleeping
	 */
	private int sleepingThreads = 0;
	/**
	 * The living set of workers in this pool.
	 */
	private Worker[] threads = new Worker[10];

	protected WorkerPool(JobManager manager) {
		this.manager = manager;
		this.defaultContextLoader = Thread.currentThread().getContextClassLoader();
	}

	/**
	 * Adds a worker to the list of workers.
	 */
	private synchronized void add(Worker worker) {
		int size = threads.length;
		if (numThreads + 1 > size) {
			Worker[] newThreads = new Worker[2 * size];
			System.arraycopy(threads, 0, newThreads, 0, size);
			threads = newThreads;
		}
		threads[numThreads++] = worker;
	}

	private synchronized void decrementBusyThreads() {
		//impossible to have less than zero busy threads
		if (--busyThreads < 0) {
			if (JobManager.DEBUG)
				Assert.isTrue(false, Integer.toString(busyThreads));
			busyThreads = 0;
		}
	}

	/**
	 * Signals the end of a job.  Note that this method can be called under
	 * OutOfMemoryError conditions and thus must be paranoid about allocating objects.
	 */
	protected void endJob(InternalJob job, IStatus result) {
		try {
			//need to end rule in graph before ending job so that 2 threads
			//do not become the owners of the same rule in the graph
			if ((job.getRule() != null) && !(job instanceof ThreadJob)) {
				//remove any locks this thread may be owning on that rule
				manager.getLockManager().removeLockCompletely(Thread.currentThread(), job.getRule());
			}
			manager.endJob(job, result, true);
			//ensure this thread no longer owns any scheduling rules
			manager.implicitJobs.endJob(job);
		} finally {
			decrementBusyThreads();
		}
	}

	/**
	 * Signals the death of a worker thread.  Note that this method can be called under
	 * OutOfMemoryError conditions and thus must be paranoid about allocating objects.
	 */
	protected synchronized void endWorker(Worker worker) {
		if (remove(worker) && JobManager.DEBUG)
			JobManager.debug("worker removed from pool: " + worker); //$NON-NLS-1$
	}

	private synchronized void incrementBusyThreads() {
		//impossible to have more busy threads than there are threads
		if (++busyThreads > numThreads) {
			if (JobManager.DEBUG)
				Assert.isTrue(false, Integer.toString(busyThreads) + ',' + numThreads);
			busyThreads = numThreads;
		}
	}

	/**
	 * Notification that a job has been added to the queue. Wake a worker,
	 * creating a new worker if necessary. The provided job may be null.
	 */
	protected synchronized void jobQueued() {
		//if there is a sleeping thread, wake it up
		if (sleepingThreads > 0) {
			notify();
			return;
		}
		//create a thread if all threads are busy
		if (busyThreads >= numThreads) {
			Worker worker = new Worker(this);
			worker.setDaemon(isDaemon);
			add(worker);
			if (JobManager.DEBUG)
				JobManager.debug("worker added to pool: " + worker); //$NON-NLS-1$
			worker.start();
			return;
		}
	}

	/**
	 * Remove a worker thread from our list.
	 * @return true if a worker was removed, and false otherwise.
	 */
	private synchronized boolean remove(Worker worker) {
		for (int i = 0; i < threads.length; i++) {
			if (threads[i] == worker) {
				System.arraycopy(threads, i + 1, threads, i, numThreads - i - 1);
				threads[--numThreads] = null;
				return true;
			}
		}
		return false;
	}

	/**
	 * Sets whether threads created in the worker pool should be daemon threads.
	 */
	void setDaemon(boolean value) {
		this.isDaemon = value;
	}

	protected synchronized void shutdown() {
		notifyAll();
	}

	/**
	 * Sleep for the given duration or until woken.
	 */
	private synchronized void sleep(long duration) {
		sleepingThreads++;
		busyThreads--;
		if (JobManager.DEBUG)
			JobManager.debug("worker sleeping for: " + duration + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			wait(duration);
		} catch (InterruptedException e) {
			if (JobManager.DEBUG)
				JobManager.debug("worker interrupted while waiting... :-|"); //$NON-NLS-1$
		} finally {
			sleepingThreads--;
			busyThreads++;
		}
	}

	/**
	 * Returns a new job to run. Returns null if the thread should die.
	 */
	protected InternalJob startJob(Worker worker) {
		//if we're above capacity, kill the thread
		synchronized (this) {
			if (!manager.isActive()) {
				//must remove the worker immediately to prevent all threads from expiring
				endWorker(worker);
				return null;
			}
			//set the thread to be busy now in case of reentrant scheduling
			incrementBusyThreads();
		}
		Job job = null;
		try {
			job = manager.startJob(worker);
			//spin until a job is found or until we have been idle for too long
			long idleStart = System.currentTimeMillis();
			while (manager.isActive() && job == null) {
				long hint = manager.sleepHint();
				if (hint > 0)
					sleep(Math.min(hint, BEST_BEFORE));
				job = manager.startJob(worker);
				//if we were already idle, and there are still no new jobs, then
				// the thread can expire
				synchronized (this) {
					if (job == null && (System.currentTimeMillis() - idleStart > BEST_BEFORE) && (numThreads - busyThreads) > MIN_THREADS) {
						//must remove the worker immediately to prevent all threads from expiring
						endWorker(worker);
						return null;
					}
				}
				//if we didn't sleep but there was no job available, make sure we sleep to avoid a tight loop (bug 260724)
				if (hint <= 0 && job == null)
					sleep(50);
			}
			if (job != null) {
				//if this job has a rule, then we are essentially acquiring a lock
				if ((job.getRule() != null) && !(job instanceof ThreadJob)) {
					//don't need to re-acquire locks because it was not recorded in the graph
					//that this thread waited to get this rule
					manager.getLockManager().addLockThread(Thread.currentThread(), job.getRule());
				}
				//see if we need to wake another worker
				if (manager.sleepHint() < InternalJob.T_INFINITE)
					jobQueued();
			}
		} finally {
			//decrement busy thread count if we're not running a job
			if (job == null)
				decrementBusyThreads();
		}
		return job;
	}
}
