1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

[179293] Added cancel listener to RequestMonitor. Added handleWarning() completion handler.

This commit is contained in:
Pawel Piech 2008-03-25 20:38:29 +00:00
parent 42eb4e884e
commit 7d6b83a35f

View file

@ -14,10 +14,10 @@ import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.internal.DsfPlugin; import org.eclipse.dd.dsf.internal.DsfPlugin;
import org.eclipse.dd.dsf.service.IDsfService;
/** /**
* Used to monitor the result of an asynchronous request. Because of the * Used to monitor the result of an asynchronous request. Because of the
@ -56,6 +56,22 @@ import org.eclipse.dd.dsf.service.IDsfService;
*/ */
@ConfinedToDsfExecutor("") @ConfinedToDsfExecutor("")
public class RequestMonitor { public class RequestMonitor {
/**
* Interface used by RequestMonitor to notify when a given request monitor
* is canceled.
*
* @see RequestMonitor
*/
public static interface ICanceledListener {
/**
* Called when the given request monitor is canceled.
*/
public void requestCanceled(RequestMonitor rm);
}
public static final IStatus STATUS_CANCEL = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, "Request canceled"); //$NON-NLS-1$ public static final IStatus STATUS_CANCEL = new Status(IStatus.CANCEL, DsfPlugin.PLUGIN_ID, "Request canceled"); //$NON-NLS-1$
/** /**
@ -70,6 +86,8 @@ public class RequestMonitor {
*/ */
private final RequestMonitor fParentRequestMonitor; private final RequestMonitor fParentRequestMonitor;
private ListenerList fCancelListeners;
/** /**
* Status * Status
*/ */
@ -87,6 +105,18 @@ public class RequestMonitor {
public RequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) { public RequestMonitor(Executor executor, RequestMonitor parentRequestMonitor) {
fExecutor = executor; fExecutor = executor;
fParentRequestMonitor = parentRequestMonitor; fParentRequestMonitor = parentRequestMonitor;
// If the parent rm is not null, add ourselves as a listener so that
// this request monitor will automatically be canceled when the parent
// is canceled.
if (fParentRequestMonitor != null) {
fParentRequestMonitor.addCancelListener(
new ICanceledListener() {
public void requestCanceled(RequestMonitor rm) {
cancel();
}
});
}
} }
/** /**
@ -101,16 +131,26 @@ public class RequestMonitor {
} }
/** /**
* Sets this request as canceled. The operation may still be carried out * Sets this request monitor as canceled and calls the cancel listeners if any.
* as it is up to the implementation of the asynchronous operation * The operation may still be carried out as it is up to the implementation of
* to cancel the operation. * the asynchronous operation to cancel the operation. Even after the request
* @param canceled Flag indicating whether to cancel. * monitor is canceled, the done() method still has to be called.
*/ */
public synchronized void setCanceled(boolean canceled) { public void cancel() {
if (fParentRequestMonitor != null) { Object[] listeners = null;
fParentRequestMonitor.setCanceled(canceled); synchronized (this) {
} else { fCanceled = true;
fCanceled = canceled; if (fCancelListeners != null) {
listeners = fCancelListeners.getListeners();
}
}
// Call the listeners outsize of a synchronized section to reduce the
// risk of deadlocks.
if (listeners != null) {
for (Object listener : listeners) {
((ICanceledListener)listener).requestCanceled(this);
}
} }
} }
@ -121,11 +161,29 @@ public class RequestMonitor {
* of the request monitor. * of the request monitor.
*/ */
public synchronized boolean isCanceled() { public synchronized boolean isCanceled() {
if (fParentRequestMonitor != null) {
return fParentRequestMonitor.isCanceled();
} else {
return fCanceled; return fCanceled;
} }
/**
* Adds the given listener to list of listeners that are notified when this
* request monitor is canceled.
*/
public synchronized void addCancelListener(ICanceledListener listener) {
if (fCancelListeners == null) {
fCancelListeners = new ListenerList();
}
fCancelListeners.add(listener);
}
/**
* Removes the given listener from the list of listeners that are notified
* when this request monitor is canceled.
*/
public synchronized void removeCancelListener(ICanceledListener listener) {
if (fCancelListeners == null) {
fCancelListeners = new ListenerList();
}
fCancelListeners.remove(listener);
} }
/** /**
@ -165,7 +223,7 @@ public class RequestMonitor {
/** /**
* Default handler for the completion of a request. The implementation * Default handler for the completion of a request. The implementation
* calls {@link #handleOK()} if the request succeeded, and calls * calls {@link #handleOK()} if the request succeeded, and calls
* {@link #handleErrorOrCancel()} or cancel otherwise. * {@link #handleCancelOrErrorOrWarning()} or cancel otherwise.
* <br> * <br>
* Note: Sub-classes may override this method. * Note: Sub-classes may override this method.
*/ */
@ -173,7 +231,7 @@ public class RequestMonitor {
if (getStatus().isOK()) { if (getStatus().isOK()) {
handleOK(); handleOK();
} else { } else {
handleErrorOrCancel(); handleCancelOrErrorOrWarning();
} }
} }
@ -181,7 +239,7 @@ public class RequestMonitor {
* Default handler for a successful the completion of a request. If this * Default handler for a successful the completion of a request. If this
* monitor has a parent monitor that was configured by the constructor, that * monitor has a parent monitor that was configured by the constructor, that
* parent monitor is notified. Otherwise this method does nothing. * parent monitor is notified. Otherwise this method does nothing.
* {@link #handleErrorOrCancel()} or cancel otherwise. * {@link #handleCancelOrErrorOrWarning()} or cancel otherwise.
* <br> * <br>
* Note: Sub-classes may override this method. * Note: Sub-classes may override this method.
*/ */
@ -194,27 +252,46 @@ public class RequestMonitor {
/** /**
* The default implementation of a cancellation or an error result of a * The default implementation of a cancellation or an error result of a
* request. The implementation delegates to {@link #handleCancel()} and * request. The implementation delegates to {@link #handleCancel()} and
* {@link #handleError()} as needed. * {@link #handleErrorOrWarning()} as needed.
* <br> * <br>
* Note: Sub-classes may override this method. * Note: Sub-classes may override this method.
*/ */
protected void handleErrorOrCancel() { protected void handleCancelOrErrorOrWarning() {
assert !getStatus().isOK(); assert !getStatus().isOK();
if (isCanceled()) { if (isCanceled()) {
handleCancel(); handleCancel();
} else { } else {
if (getStatus().getCode() == IStatus.CANCEL) { if (getStatus().getSeverity() == IStatus.CANCEL) {
DsfPlugin.getDefault().getLog().log(new Status( DsfPlugin.getDefault().getLog().log(new Status(
IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request monitor: '" + this + "' resulted in a cancel status: " + getStatus() + ", even though the request is not set to cancel.", null)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ IStatus.ERROR, DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request monitor: '" + this + "' resulted in a cancel status: " + getStatus() + ", even though the request is not set to cancel.", null)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
} }
if (getStatus().getSeverity() == IStatus.ERROR) {
handleError(); handleError();
} else {
handleWarning();
}
}
}
/**
* The default implementation of an error or warning result of a request.
* The implementation delegates to {@link #handleError()} and
* {@link #handleWarning()} as needed.
* <br>
* Note: Sub-classes may override this method.
*/
protected void handleErrorOrWarning() {
if (getStatus().getSeverity() == IStatus.ERROR) {
handleError();
} else {
handleWarning();
} }
} }
/** /**
* The default implementation of an error result of a request. If this * The default implementation of an error result of a request. If this
* monitor has a parent monitor that was configured by the constructor, that * monitor has a parent monitor that was configured by the constructor, that
* parent monitor is configured with a new error status containing this error. * parent monitor is configured with a new status containing this error.
* Otherwise the error is logged. * Otherwise the error is logged.
* <br> * <br>
* Note: Sub-classes may override this method. * Note: Sub-classes may override this method.
@ -224,7 +301,26 @@ public class RequestMonitor {
fParentRequestMonitor.setStatus(getStatus()); fParentRequestMonitor.setStatus(getStatus());
fParentRequestMonitor.done(); fParentRequestMonitor.done();
} else { } else {
MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in an error.", null); //$NON-NLS-1$ //$NON-NLS-2$ MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in an error.", null); //$NON-NLS-1$ //$NON-NLS-2$
logStatus.merge(getStatus());
DsfPlugin.getDefault().getLog().log(logStatus);
}
}
/**
* The default implementation of an error result of a request. If this
* monitor has a parent monitor that was configured by the constructor, that
* parent monitor is configured with a new status containing this warning.
* Otherwise the warning is logged.
* <br>
* Note: Sub-classes may override this method.
*/
protected void handleWarning() {
if (fParentRequestMonitor != null) {
fParentRequestMonitor.setStatus(getStatus());
fParentRequestMonitor.done();
} else {
MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a warning.", null); //$NON-NLS-1$ //$NON-NLS-2$
logStatus.merge(getStatus()); logStatus.merge(getStatus());
DsfPlugin.getDefault().getLog().log(logStatus); DsfPlugin.getDefault().getLog().log(logStatus);
} }
@ -250,7 +346,7 @@ public class RequestMonitor {
* This usually happens only when the executor is shutting down. * This usually happens only when the executor is shutting down.
*/ */
protected void handleRejectedExecutionException() { protected void handleRejectedExecutionException() {
MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null); //$NON-NLS-1$ //$NON-NLS-2$ MultiStatus logStatus = new MultiStatus(DsfPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Request for monitor: '" + toString() + "' resulted in a rejected execution exception.", null); //$NON-NLS-1$ //$NON-NLS-2$
logStatus.merge(getStatus()); logStatus.merge(getStatus());
if (fParentRequestMonitor != null) { if (fParentRequestMonitor != null) {
fParentRequestMonitor.setStatus(logStatus); fParentRequestMonitor.setStatus(logStatus);