/* * Copyright (c) 2010 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ /* * Copyright (c) 2010-2018, Isode Limited, London, England. * All rights reserved. */ package com.isode.stroke.network; import com.isode.stroke.eventloop.Event; import com.isode.stroke.eventloop.EventLoop; import com.isode.stroke.eventloop.EventOwner; class JavaTimer extends Timer { private class TimerRunnable implements Runnable,EventOwner { private boolean running_ = true; private final EventLoop eventLoop_; private final long milliseconds_; public TimerRunnable(EventLoop eventLoop, long milliseconds) { eventLoop_ = eventLoop; milliseconds_ = milliseconds; } public void run() { long endTime = System.currentTimeMillis() + milliseconds_; while (shouldEmit() && System.currentTimeMillis() < endTime) { try { long timeToWait = endTime - System.currentTimeMillis(); if (timeToWait > 0) { Thread.sleep(timeToWait); } } catch (InterruptedException ex) { // Needs to be caught, but won't break out of the loop // unless end time reached or stop() has been called. } } synchronized(this) { if (shouldEmit()) { eventLoop_.postEvent(new Event.Callback() { public void run() { onTick.emit(); } },this); } } } synchronized boolean shouldEmit() { return running_; } public synchronized void stop() { running_ = false; timer_.eventLoop_.removeEventsFromOwner(this); } } /** * Create a new JavaTimer * @param eventLoop the caller's EventLoop. Should not be null. * @param milliseconds length of delay. */ public JavaTimer(EventLoop eventLoop, long milliseconds) { timer_ = new TimerRunnable(eventLoop, milliseconds); } /** * Start the timer running. The timer will expire and generate a signal * after the specified delay, unless {@link #stop()} has been called. */ @Override public void start() { Thread thread = (new Thread(timer_)); thread.setDaemon(true); thread.start(); } /** * Cancel the timer. No signal will be generated. */ @Override public void stop() { timer_.stop(); } @Override public String toString() { synchronized (timer_) { return "JavaTimer for " + timer_.milliseconds_ + " milliseconds " + (timer_.running_ ? "running" : "not running"); } } private final TimerRunnable timer_; }