Package freenet.support

Source Code of freenet.support.TrivialTicker

package freenet.support;

import java.util.Hashtable;
import java.util.Timer;
import java.util.TimerTask;

import freenet.node.FastRunnable;

/**
* Ticker implemented using Timer's.
*
* If deploying this to replace PacketSender, be careful to handle priority changes properly.
* Hopefully that can be achieved simply by creating at max priority during startup.
*
* @author Matthew Toseland <toad@amphibian.dyndns.org> (0xE43DA450)
*
*/
public class TrivialTicker implements Ticker {

  private final Timer timer = new Timer(true);
 
  private final Executor executor;
 
  private final Hashtable<Runnable, TimerTask> jobs = new Hashtable<Runnable, TimerTask>();
 
  private boolean running = true;
 
  public TrivialTicker(Executor executor) {
    this.executor = executor;
  }
 
  @Override
  public void queueTimedJob(final Runnable job, long offset) {
    TimerTask t = new TimerTask() {
      @Override
      public void run() {
        synchronized(TrivialTicker.this) {
          jobs.remove(job); // We must do this before job.run() in case the job re-schedules itself.
        }
       
        if(job instanceof FastRunnable) {
          job.run();
        } else {
          executor.execute(job, "Delayed task: "+job);
        }
      }
    };
   
    synchronized(this) {
      if(!running)
        return;
   
      timer.schedule(t, offset);
      jobs.put(job, t);
    }
  }

  @Override
  public void queueTimedJob(final Runnable job, final String name, long offset,
      boolean runOnTickerAnyway, boolean noDupes) {
    TimerTask t = new TimerTask() {

      @Override
      public void run() {
        synchronized(TrivialTicker.this) {
          jobs.remove(job); // We must do this before job.run() in case the job re-schedules itself.
        }
       
        if(job instanceof FastRunnable) {
          job.run();
        } else {
          executor.execute(job, name);
        }
      }
     
    };
   
    synchronized(this) {
      if(!running)
        return;
     
      if(noDupes && jobs.containsKey(job))
        return;
     
      timer.schedule(t, offset);
      jobs.put(job, t);
    }
  }
 
  public void cancelTimedJob(final Runnable job) {
    removeQueuedJob(job);
  }
 
  @Override
  public void removeQueuedJob(final Runnable job) {
    synchronized(this) {
      if(!running)
        return;
     
      TimerTask t = jobs.remove(job);
      if(t != null) {
        t.cancel();
      }
    }
  }
 
  /**
   * Changes the offset of a already-queued job.
   * If the given job was not queued yet it will be queued nevertheless.
   */
  public void rescheduleTimedJob(final Runnable job, final String name, long newOffset) {
    synchronized(this) {
      removeQueuedJob(job);
      queueTimedJob(job, name, newOffset, false, false); // Don't dupe-check, we are synchronized
    }
  }
 
  private Thread shutdownThread = null;
 
  public void shutdown() {
    synchronized(this) {
      running = false;
     
      timer.schedule(new TimerTask() {

        @Override
        public void run() {
          // According to the JavaDoc of cancel(), calling it inside a TimerTask guarantees that the task is the last one which is run.
          timer.cancel();
          synchronized(TrivialTicker.this) {
            shutdownThread = Thread.currentThread();
            TrivialTicker.this.notifyAll();
          }
        }
       
      }, 0);
     
      while(shutdownThread == null) {
        try {
          wait();
        } catch (InterruptedException e) { } // Valid to happen due to spurious wakeups
      }
     
      while(shutdownThread.isAlive()) { // Ignore InterruptedExceptions
        try {
          shutdownThread.join();
        } catch (InterruptedException e) {
          Logger.error(this, "Got an unexpected InterruptedException", e);
        }
      }
    }
  }

  @Override
  public Executor getExecutor() {
    return executor;
  }

}
TOP

Related Classes of freenet.support.TrivialTicker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.