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:
parent
42eb4e884e
commit
7d6b83a35f
1 changed files with 122 additions and 26 deletions
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue