All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ch.ethz.ssh2.util.TimeoutService Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2006-2011 Christian Plattner. All rights reserved.
 * Please refer to the LICENSE.txt for licensing details.
 */

package ch.ethz.ssh2.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;

import ch.ethz.ssh2.log.Logger;

/**
 * TimeoutService (beta). Here you can register a timeout.
 * 

* Implemented having large scale programs in mind: if you open many concurrent SSH connections * that rely on timeouts, then there will be only one timeout thread. Once all timeouts * have expired/are cancelled, the thread will (sooner or later) exit. * Only after new timeouts arrive a new thread (singleton) will be instantiated. * * @author Christian Plattner * @version $Id: TimeoutService.java 89 2014-04-07 14:36:24Z [email protected] $ */ public class TimeoutService { private static final Logger log = Logger.getLogger(TimeoutService.class); public static class TimeoutToken { private long runTime; private Runnable handler; private TimeoutToken(long runTime, Runnable handler) { this.runTime = runTime; this.handler = handler; } } private static class TimeoutThread extends Thread { @Override public void run() { synchronized (todolist) { while (true) { if (todolist.size() == 0) { timeoutThread = null; return; } long now = System.currentTimeMillis(); TimeoutToken tt = todolist.getFirst(); if (tt.runTime > now) { /* Not ready yet, sleep a little bit */ try { todolist.wait(tt.runTime - now); } catch (InterruptedException ignored) { } /* We cannot simply go on, since it could be that the token * was removed (cancelled) or another one has been inserted in * the meantime. */ continue; } todolist.removeFirst(); try { tt.handler.run(); } catch (Exception e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); log.warning("Exeception in Timeout handler:" + e.getMessage() + "(" + sw.toString() + ")"); } } } } } /* The list object is also used for locking purposes */ private static final LinkedList todolist = new LinkedList(); private static Thread timeoutThread = null; /** * It is assumed that the passed handler will not execute for a long time. * * @param runTime * @param handler * @return a TimeoutToken that can be used to cancel the timeout. */ public static TimeoutToken addTimeoutHandler(long runTime, Runnable handler) { TimeoutToken token = new TimeoutToken(runTime, handler); synchronized (todolist) { todolist.add(token); Collections.sort(todolist, new Comparator() { public int compare(TimeoutToken o1, TimeoutToken o2) { if (o1.runTime > o2.runTime) return 1; if (o1.runTime == o2.runTime) return 0; return -1; } }); if (timeoutThread != null) timeoutThread.interrupt(); else { timeoutThread = new TimeoutThread(); timeoutThread.setDaemon(true); timeoutThread.start(); } } return token; } public static void cancelTimeoutHandler(TimeoutToken token) { synchronized (todolist) { todolist.remove(token); if (timeoutThread != null) timeoutThread.interrupt(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy