| /* |
| * 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.geode; |
| |
| /** |
| * Abstract cancellation proxy for cancelling an operation, esp. a thread. |
| * |
| * Creators of services or threads should implement a subclass of CancelCriterion, and implement the |
| * two methods - cancelInProgress, and generateCancelledException(e). |
| * |
| * Code inside the service can check to see if the service is cancelled by calling |
| * {@link #checkCancelInProgress(Throwable)}. Generally the pattern is to check before performing an |
| * operation, check if the service is canceled before propagating an exception further up the stack, |
| * and check for cancellation inside a long loop. Eg. |
| * |
| * <pre> |
| * while (true) { |
| * c.checkCancelInProgress(null); |
| * try { |
| * dispatchEvents(); |
| * } catch (IOException e) { |
| * c.checkCancelInProgress(e); |
| * throw e; |
| * } |
| * } |
| * </pre> |
| * |
| * @see CancelException |
| * @since GemFire 5.1 |
| */ |
| public abstract class CancelCriterion { |
| |
| /** |
| * Indicate if the service is in the progress of being cancelled. The typical use of this is to |
| * indicate, in the case of an {@link InterruptedException}, that the current operation should be |
| * cancelled. |
| * |
| * @return null if the service is not shutting down, or a message that can be used to construct an |
| * exception indicating the service is shut down. |
| */ |
| public abstract String cancelInProgress(); |
| |
| /** |
| * Use this utility function in your implementation of cancelInProgress() and cancelled() to |
| * indicate a system failure |
| * |
| * @return failure string if system failure has occurred |
| */ |
| protected String checkFailure() { |
| Throwable tilt = SystemFailure.getFailure(); |
| if (tilt != null) { |
| // Allocate no objects here! |
| return SystemFailure.JVM_CORRUPTION; |
| } |
| return null; |
| } |
| |
| /** |
| * See if the current operation is being cancelled. If so, it either throws a |
| * {@link RuntimeException} (usually a {@link CancelException}). |
| * |
| * @param e an underlying exception or null if there is no exception that triggered this check |
| * @see #cancelInProgress() |
| */ |
| public void checkCancelInProgress(Throwable e) { |
| SystemFailure.checkFailure(); |
| String reason = cancelInProgress(); |
| if (reason == null) { |
| return; |
| } |
| throw generateCancelledException(e); |
| } |
| |
| public void checkCancelInProgress() { |
| checkCancelInProgress(null); |
| } |
| |
| /** |
| * Template factory method for generating the exception to be thrown by |
| * {@link #checkCancelInProgress(Throwable)}. Override this to specify different exception for |
| * checkCancelInProgress() to throw. |
| * |
| * This method should wrap the exception in a service specific CancelationException (eg |
| * CacheClosedException). or return null if the service is not being canceled. |
| * |
| * @param throwable an underlying exception, if any |
| * @return RuntimeException to be thrown by checkCancelInProgress(), null if the receiver has not |
| * been cancelled. |
| */ |
| public abstract RuntimeException generateCancelledException(Throwable throwable); |
| |
| /** |
| * Checks to see if a cancellation is in progress. This is equivalent to the expression |
| * (cancelInProgress() != null). |
| * |
| * @return true if a cancellation is in progress, false if not |
| */ |
| public boolean isCancelInProgress() { |
| return cancelInProgress() != null; |
| } |
| |
| } |