| /******************************************************************************* |
| * Copyright (c) 2000, 2011 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.debug.core.model; |
| |
| /** |
| * A timer notifies listeners when a specific amount of time has passed. |
| * |
| * @see ITimeoutListener |
| */ |
| public class Timer { |
| |
| /** |
| * Listener to notify of a timeout |
| */ |
| private ITimeoutListener fListener; |
| |
| /** |
| * Timeout value, in milliseconds |
| */ |
| private int fTimeout; |
| |
| /** |
| * Whether this timer's thread is alive |
| */ |
| private boolean fAlive = true; |
| |
| /** |
| * Whether this timer has been started and has not yet timed out or been |
| * stopped. |
| */ |
| private boolean fStarted = false; |
| |
| /** |
| * The single thread used for each request. |
| */ |
| private Thread fThread; |
| |
| /** |
| * Constructs a new timer |
| */ |
| public Timer() { |
| setTimeout(Integer.MAX_VALUE); |
| Runnable r = new Runnable() { |
| @Override |
| public void run() { |
| while (isAlive()) { |
| boolean interrupted = false; |
| try { |
| Thread.sleep(getTimeout()); |
| } catch (InterruptedException e) { |
| interrupted = true; |
| } |
| if (!interrupted) { |
| if (getListener() != null) { |
| setStarted(false); |
| setTimeout(Integer.MAX_VALUE); |
| getListener().timeout(); |
| setListener(null); |
| } |
| } |
| } |
| } |
| }; |
| setThread(new Thread(r, "Evaluation Timer")); //$NON-NLS-1$ |
| getThread().setDaemon(true); |
| getThread().start(); |
| } |
| |
| /** |
| * Starts this timer, and notifies the given listener when the time has |
| * passed. A call to <code>stop</code>, before the time expires, will cancel |
| * the the timer and timeout callback. This method can only be called if |
| * this timer is idle (i.e. <code>isStarted() == false<code>). |
| * |
| * @param listener |
| * The timer listener |
| * @param ms |
| * The number of milliseconds to wait before notifying the |
| * listener |
| */ |
| public void start(ITimeoutListener listener, int ms) { |
| if (isStarted()) { |
| throw new IllegalStateException( |
| JDIDebugModelMessages.Timer_Timer_cannot_be_started_more_than_once_1); |
| } |
| setListener(listener); |
| setTimeout(ms); |
| setStarted(true); |
| getThread().interrupt(); |
| } |
| |
| /** |
| * Stops this timer, cancelling any pending timeout notification. |
| */ |
| public void stop() { |
| if (isAlive()) { |
| setStarted(false); |
| setTimeout(Integer.MAX_VALUE); |
| getThread().interrupt(); |
| } |
| } |
| |
| /** |
| * Disposes this timer |
| */ |
| public void dispose() { |
| if (isAlive()) { |
| setAlive(false); |
| getThread().interrupt(); |
| setThread(null); |
| } |
| } |
| |
| /** |
| * Returns whether this timer's thread is alive |
| * |
| * @return whether this timer's thread is alive |
| */ |
| private boolean isAlive() { |
| return fAlive; |
| } |
| |
| /** |
| * Sets whether this timer's thread is alive. When set to <code>false</code> |
| * this timer's thread will exit on its next iteration. |
| * |
| * @param alive |
| * whether this timer's thread should be alive |
| * @see #dispose() |
| */ |
| private void setAlive(boolean alive) { |
| fAlive = alive; |
| } |
| |
| /** |
| * Returns the current timeout listener |
| * |
| * @return timeout listener |
| */ |
| protected ITimeoutListener getListener() { |
| return fListener; |
| } |
| |
| /** |
| * Sets the listener to be notified if this timer times out. |
| * |
| * @param listener |
| * timeout listener |
| */ |
| private void setListener(ITimeoutListener listener) { |
| fListener = listener; |
| } |
| |
| /** |
| * Returns whether this timer has been started, and has not yet timed out, |
| * or been stopped. |
| * |
| * @return whether this timer has been started, and has not yet timed out, |
| * or been stopped |
| */ |
| public boolean isStarted() { |
| return fStarted; |
| } |
| |
| /** |
| * Sets whether this timer has been started, and has not yet timed out, or |
| * been stopped. |
| * |
| * @param started |
| * whether this timer has been started, and has not yet timed |
| * out, or been stopped |
| */ |
| private void setStarted(boolean started) { |
| fStarted = started; |
| } |
| |
| /** |
| * Returns this timer's thread |
| * |
| * @return thread that waits for a timeout |
| */ |
| private Thread getThread() { |
| return fThread; |
| } |
| |
| /** |
| * Sets this timer's thread used to perform timeout processing |
| * |
| * @param thread |
| * thread that waits for a timeout |
| */ |
| private void setThread(Thread thread) { |
| fThread = thread; |
| } |
| |
| /** |
| * Returns the amount of time, in milliseconds, that this timer is/was |
| * waiting for. |
| * |
| * @return timeout value, in milliseconds |
| */ |
| protected int getTimeout() { |
| return fTimeout; |
| } |
| |
| /** |
| * Sets the amount of time, in milliseconds, that this timer will wait for |
| * before timing out. |
| * |
| * @param timeout |
| * value, in milliseconds |
| */ |
| private void setTimeout(int timeout) { |
| fTimeout = timeout; |
| } |
| } |