/** * Cancel the execution of this task and make sure it can never be * scheduled for execution again. After this method is invoked, * invoking the {@link #schedule schedule} and {@link #scheduleNow * scheduleNow} methods will have no effect. * * @return true if the task was scheduled and we managed to avoid * execution **/ public boolean kill() { return owner.kill(this); } }
/** * Schedule this task for execution. A task may be scheduled * multiple times, but may only have a single pending execution * time. Re-scheduling a task that is not yet run will move the * execution time. If the task has already been executed, * scheduling works just like if the task was never run. * * @param seconds the number of seconds until the task should be * executed * @see #kill **/ public void schedule(double seconds) { owner.schedule(this, seconds); }
/** * Cancel the execution of this task. * * @return true if the task was scheduled and we managed to avoid * execution **/ public boolean unschedule() { return owner.unschedule(this); }
/** * Schedule this task for execution as soon as possible. This will * result in the task being executed the next time the reactor * loop inside the owning {@link Transport} object checks for * tasks to run. If you have something that is even more urgent, * or something you need to be executed even if the {@link * Transport} is shut down, use the {@link Transport#perform} * method instead. * @see #kill **/ public void scheduleNow() { owner.scheduleNow(this); }
public void checkTasks(long now) { if (slots[SLOTS] == null && now < nextTick) { return; } synchronized (this) { queueTasks(SLOTS, 0); for (int i = 0; now >= nextTick; i++, nextTick += TICK) { if (i < 3) { if (++currSlot >= SLOTS) { currSlot = 0; currIter++; } queueTasks(currSlot, currIter); } } } while (!queue.isEmpty()) { Task task = (Task) queue.dequeue(); task.perform(); } } }
private void queueTasks(int slot, int iter) { int cnt = counts[slot]; Task task = slots[slot]; for (int i = 0; i < cnt; i++) { Task next = task.next(); if (task.iter() == iter) { linkOut(task); queue.enqueue(task); } task = next; } }
/** * Create a new Transport object with the given fatal error * handler and CryptoEngine. If a fatal error occurs when no fatal * error handler is registered, the default action is to log the * error and exit with exit code 1. * * @param fatalHandler fatal error handler * @param cryptoEngine crypto engine to use **/ public Transport(FatalErrorHandler fatalHandler, CryptoEngine cryptoEngine) { synchronized (this) { this.fatalHandler = fatalHandler; // NB: this must be set first } this.cryptoEngine = cryptoEngine; thread = new Thread(new Run(), "<jrt-transport>"); queue = new Queue(); myQueue = new Queue(); connector = new Connector(this); closer = new Closer(this); scheduler = new Scheduler(System.currentTimeMillis()); state = OPEN; try { selector = Selector.open(); } catch (Exception e) { throw new Error("Could not open transport selector", e); } thread.setDaemon(true); thread.start(); } public Transport(CryptoEngine cryptoEngine) { this(null, cryptoEngine); }
scheduler.checkTasks(System.currentTimeMillis());
public synchronized void schedule(Task task, double seconds) { if (task.isKilled()) { return; } if (seconds < 0.0) { throw new IllegalArgumentException("cannot schedule a Task in the past"); } int ticks = 1 + (int) (seconds * 10.0 + 0.5); if (isActive(task)) { linkOut(task); } task.slot((ticks + currSlot) & MASK); task.iter(currIter + ((ticks + currSlot) >> SHIFT)); linkIn(task); }