All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tools.ant.util.WorkerAnt Maven / Gradle / Ivy

There is a newer version: 1.10.15
Show newest version
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.tools.ant.util;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

/**
 * A worker ant executes a single task in a background thread.
 * After the run, any exception thrown is turned into a buildexception, which can be
 * rethrown, the finished attribute is set, then notifyAll() is called,
 * so that anyone waiting on the same notify object gets woken up.
 * 

* This class is effectively a superset of * {@link org.apache.tools.ant.taskdefs.Parallel.TaskRunnable} * * @since Ant 1.8 */ public class WorkerAnt extends Thread { private Task task; private Object notify; private volatile boolean finished = false; private volatile BuildException buildException; private volatile Throwable exception; /** * Error message if invoked with no task */ public static final String ERROR_NO_TASK = "No task defined"; /** * Create the worker. *

* This does not start the thread, merely configures it. * @param task the task * @param notify what to notify */ public WorkerAnt(Task task, Object notify) { this.task = task; this.notify = notify != null ? notify : this; } /** * Create the worker, using the worker as the notification point. *

* This does not start the thread, merely configures it. * @param task the task */ public WorkerAnt(Task task) { this(task, null); } /** * Get any build exception. * This would seem to be oversynchronised, but know that Java pre-1.5 can * reorder volatile access. * The synchronized attribute is to force an ordering. * * @return the exception or null */ public synchronized BuildException getBuildException() { return buildException; } /** * Get whatever was thrown, which may or may not be a buildException. * Assertion: getException() instanceof BuildException <=> getBuildException()==getException() * @return the exception. */ public synchronized Throwable getException() { return exception; } /** * Get the task * @return the task */ public Task getTask() { return task; } /** * Query the task/thread for being finished. * This would seem to be oversynchronised, but know that Java pre-1.5 can * reorder volatile access. * The synchronized attribute is to force an ordering. * @return true if the task is finished. */ public synchronized boolean isFinished() { return finished; } /** * Block on the notify object and so wait until the thread is finished. * @param timeout timeout in milliseconds * @throws InterruptedException if the execution was interrupted */ public void waitUntilFinished(long timeout) throws InterruptedException { final long start = System.currentTimeMillis(); final long end = start + timeout; synchronized (notify) { long now = System.currentTimeMillis(); while (!finished && now < end) { notify.wait(end - now); now = System.currentTimeMillis(); } } } /** * Raise an exception if one was caught * * @throws BuildException if one has been picked up */ public void rethrowAnyBuildException() { BuildException ex = getBuildException(); if (ex != null) { throw ex; } } /** * Handle a caught exception, by recording it and possibly wrapping it * in a BuildException for later rethrowing. * @param thrown what was caught earlier */ private synchronized void caught(Throwable thrown) { exception = thrown; buildException = (thrown instanceof BuildException) ? (BuildException) thrown : new BuildException(thrown); } /** * Run the task, which is skipped if null. * When invoked again, the task is re-run. */ public void run() { try { if (task != null) { task.execute(); } } catch (Throwable thrown) { caught(thrown); } finally { synchronized (notify) { finished = true; //reset the task. //wake up our owner, if it is waiting notify.notifyAll(); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy