/*******************************************************************************
* Copyright (c) 2007, 2010 Ericsson 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:
* Ericsson - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.framework;
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
public class AsyncCompletionWaitor {
/*
* Indicates we will wait forever. Otherwise the time specified
* is in milliseconds.
*/
public final static int WAIT_FOREVER = 0;
/*
* Private control space.
*/
private IStatus fStatus;
private Object fReturnInfo;
private boolean fWaitFinished;
private int fNumWaiting;
/*
* Main constructor.
*/
public AsyncCompletionWaitor() {
waitReset();
}
/**
* A timeout of WAIT_FOREVER indicates we wait until the operation is
* completed by a call to waitFinished. Or if we are interrupted with an
* exception.
*
* @param timeout the maximum time to wait in milliseconds
*
* @throws InterruptedException
*/
public synchronized void waitUntilDone(int timeout) throws InterruptedException {
if (fWaitFinished) return;
wait(timeout);
}
/**
* Indicates that we are done with the operation and the code
* waiting ( waitUntilDone ) will be allowed to continue.
*/
public void waitFinished() {
waitFinished(new Status(IStatus.OK, TestsPlugin.PLUGIN_ID, ""));
}
public synchronized void waitFinished(IStatus status) {
if (fWaitFinished) {
((MultiStatus)fStatus).merge(
new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID,
"waitFinished called too many times!", null));
}
((MultiStatus)fStatus).merge(status);
if (fNumWaiting == 0 || --fNumWaiting == 0) {
fWaitFinished = true;
notifyAll();
}
}
/**
* Resets the state so we allow ourselves to be reused instead
* of having to create a new wait object each time.
*/
public synchronized void waitReset() {
fWaitFinished = false;
fStatus = new MultiStatus(TestsPlugin.PLUGIN_ID, 0, "", null); //$NON-NLS-1$
fReturnInfo = null;
fNumWaiting = 0;
}
public boolean isOK() {
if ( fStatus == null ) {
// We timed out
return false;
}
return fStatus.isOK();
}
public String getMessage() {
if ( fStatus == null ) {
return "Timed out"; //$NON-NLS-1$
}
// Build a concatenation of all messages
String fullMessage = "";
IStatus[] children = fStatus.getChildren();
for (int i=0; i<children.length; i++) {
if (children[i].getMessage().length() > 0) {
fullMessage += "\"" + children[i].getMessage() + "\", ";//$NON-NLS-1$//$NON-NLS-2$
}
}
// Remove the trailing comma and space before returning (as long as they are there)
return fullMessage.length() <= 2 ? fullMessage : fullMessage.substring(0, fullMessage.length() - 2);
}
public void setReturnInfo(Object info) {
fReturnInfo = info ;
}
public Object getReturnInfo() {
return fReturnInfo;
}
public void increment() {
if (fWaitFinished) {
((MultiStatus)fStatus).merge(
new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID,
"Can't increment an already finished waitor object. Waitor must be reset first.", null));
}
fNumWaiting++;
}
}