org.ros.concurrent.CancellableLoop.java Source code

Java tutorial

Introduction

Here is the source code for org.ros.concurrent.CancellableLoop.java

Source

/*
 * Copyright (C) 2011 Google Inc.
 *
 * Licensed 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.ros.concurrent;

import com.google.common.base.Preconditions;

import java.util.concurrent.ExecutorService;

/**
 * An interruptable loop that can be run by an {@link ExecutorService}.
 *
 * @author khughes@google.com (Keith M. Hughes)
 */
public abstract class CancellableLoop implements Runnable {

    private final Object mutex;

    /**
     * {@code true} if the code has been run once, {@code false} otherwise.
     */
    private boolean ranOnce = false;

    /**
     * The {@link Thread} the code will be running in.
     */
    private Thread thread;

    public CancellableLoop() {
        mutex = new Object();
    }

    @Override
    public void run() {
        synchronized (mutex) {
            Preconditions.checkState(!ranOnce, "CancellableLoops cannot be restarted.");
            ranOnce = true;
            thread = Thread.currentThread();
        }
        try {
            setup();
            while (!thread.isInterrupted()) {
                loop();
            }
        } catch (InterruptedException e) {
            handleInterruptedException(e);
        } finally {
            thread = null;

            cleanup();
        }
    }

    /**
     * The setup block for the loop. This will be called exactly once before the
     * first call to {@link #loop()}.
     */
    protected void setup() {
    }

    /**
     * The cleanup block for the loop. This will be called exactly once when the
     * loop has shut down.
     */
    protected void cleanup() {
    }

    /**
     * The body of the loop. This will run continuously until the
     * {@link CancellableLoop} has been interrupted externally or by calling
     * {@link #cancel()}.
     */
    protected abstract void loop() throws InterruptedException;

    /**
     * An {@link InterruptedException} was thrown.
     */
    protected void handleInterruptedException(InterruptedException e) {
    }

    /**
     * Interrupts the loop.
     */
    public void cancel() {
        if (thread != null) {
            thread.interrupt();
        }
    }

    /**
     * @return {@code true} if the loop is running
     */
    public boolean isRunning() {
        return thread != null && !thread.isInterrupted();
    }
}