frysk.event
Class EventLoop

java.lang.Object
  extended by java.lang.Thread
      extended by frysk.event.EventLoop
All Implemented Interfaces:
Runnable
Direct Known Subclasses:
PollEventLoop, WaitEventLoop

public abstract class EventLoop
extends Thread

Implements an event loop.


Nested Class Summary
private  class EventLoop.ExecuteRequest
           
private  class EventLoop.Running
          Run the event-loop.
 
Nested classes/interfaces inherited from class java.lang.Thread
Thread.State, Thread.UncaughtExceptionHandler
 
Field Summary
private static Log fine
           
private  Exception firstSet
           
private  boolean isGoingToBlock
          The event loop will enter a blocking poll.
private  List pendingEvents
          Maintain a FIFO of events that are ready to be processed.
private  EventLoop.ExecuteRequest request
           
private  EventLoop.Running running
           
private  Map signalHandlers
          Collection of signals; assume that very few signals are being watched and hence that a small map is sufficient.
private  boolean stop
           
private  ProcessIdentifier tid
          The EventLoop's thread ID.
private  SortedMap timerEvents
          List of timer events.
 
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Constructor Summary
protected EventLoop()
          The EventLoop uses Signal.IO to wake up, or unblock, the event-loop thread when a request comes in.
 
Method Summary
 void add(Event e)
          Add the event to the end of the queue of events that need to be processed.
 void add(SignalEvent signalEvent)
          Add the signal handler, signals are processed and then delivered using the event-loop.
 void add(TimerEvent t)
          Add a timer event that will expire at some stage in the future.
abstract  void add(WaitBuilder waitBuilder)
          Add support for the notification of waitpid events.
protected abstract  void block(long millisecondTimeout)
          Block for up-to TIMEOUT, or until an event arrives, or possibly no-reason.
private  void checkForTimerEvents()
          Move any expired timer events onto the event queue.
 void execute(Event e)
          Execute the event on the event-loop thread; return when completed.
static EventLoop factory()
          Return the current prefered flavour of the event-loop.
private  long getTimerEventMillisecondTimeout()
          Return the number of milliseconds until the next timer, or -1 if there is no pending timer (-1 implies an infinite timeout).
(package private)  boolean isCurrentThread()
           
protected  void processSignal(Signal sig)
          Process the signal.
private  Event remove()
          Remove and return the first pending event, or null if there are no pending event.
 void remove(Event e)
          Remove the pending event.
 void remove(SignalEvent signalEvent)
          Remove the signal event handler, further occurances of the signal are discarded.
 void remove(TimerEvent t)
          Remove the timer event from the event queue.
 void requestStop()
          Request that the event-loop stop.
 void run()
           
private  void runEventLoop(boolean pendingOnly)
          Run the event-loop.
 void runPending()
          Run the event loop until there are no pending events.
 boolean runPolling(long timeout)
          Run the full event loop (checking for both synchronous and asynchronous events) for at most TIMEOUT milliseconds.
protected abstract  void signalAdd(Signal sig)
          Add Signal to the signals that can be received.
protected abstract  void signalEmpty()
          Clear the signal set being used by the event-loop.
 void start()
          Start the EventLoop thread; note that this forces a brief synchronization with that thread to ensure that it is ready.
private  void updateTid()
           
private  void wakeupBlockedEventLoop()
           
private  void wakeupIfBlocked()
          If the event loop is blocking, wake it up.
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, stop, stop, suspend, toString, yield
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

fine

private static final Log fine

tid

private ProcessIdentifier tid
The EventLoop's thread ID. If a thread, other than the EventLoop thread modifies any of the event queues, the event thread will need to be woken up using a Signal.IO.


firstSet

private Exception firstSet

isGoingToBlock

private volatile boolean isGoingToBlock
The event loop will enter a blocking poll. This state is entered after the pending event queue, along with any other tasks (signals, timers), have been processed leaving the event thread with nothing to do. Should some new asynchronus task come along (such as a new event, timer, or signal handler), the event thread will need to be woken up.


timerEvents

private SortedMap timerEvents
List of timer events. Ordered by the timer's expiry time (that way the first timer event always determines the next timeout).


signalHandlers

private Map signalHandlers
Collection of signals; assume that very few signals are being watched and hence that a small map is sufficient.


pendingEvents

private List pendingEvents
Maintain a FIFO of events that are ready to be processed.


request

private final EventLoop.ExecuteRequest request

stop

private volatile boolean stop

running

private EventLoop.Running running
Constructor Detail

EventLoop

protected EventLoop()
The EventLoop uses Signal.IO to wake up, or unblock, the event-loop thread when a request comes in.

Method Detail

signalEmpty

protected abstract void signalEmpty()
Clear the signal set being used by the event-loop.


signalAdd

protected abstract void signalAdd(Signal sig)
Add Signal to the signals that can be received.


add

public abstract void add(WaitBuilder waitBuilder)
Add support for the notification of waitpid events.


block

protected abstract void block(long millisecondTimeout)
Block for up-to TIMEOUT, or until an event arrives, or possibly no-reason.


isCurrentThread

final boolean isCurrentThread()

wakeupBlockedEventLoop

private void wakeupBlockedEventLoop()

updateTid

private void updateTid()

wakeupIfBlocked

private void wakeupIfBlocked()
If the event loop is blocking, wake it up. The event loop blocks when it has nothing better to do (app pending events have been processed, all timers and signals have been handled). See remove() for where this flag is set.


add

public void add(TimerEvent t)
Add a timer event that will expire at some stage in the future. The actual time is determined by TimerEvent.getTimeMillis.


remove

public void remove(TimerEvent t)
Remove the timer event from the event queue.


getTimerEventMillisecondTimeout

private long getTimerEventMillisecondTimeout()
Return the number of milliseconds until the next timer, or -1 if there is no pending timer (-1 implies an infinite timeout).


checkForTimerEvents

private void checkForTimerEvents()
Move any expired timer events onto the event queue. Since the timer queue is ordered by time, the loop need only check the front of the queue.


add

public void add(SignalEvent signalEvent)
Add the signal handler, signals are processed and then delivered using the event-loop.


remove

public void remove(SignalEvent signalEvent)
Remove the signal event handler, further occurances of the signal are discarded.


processSignal

protected void processSignal(Signal sig)
Process the signal. Find the applicable handler and, if present, append the corresponding delivery event. Since a signal delivery un-blocks the poll, the event thread is no longer going to block.


add

public void add(Event e)
Add the event to the end of the queue of events that need to be processed. If necessary, interrupt the event thread.


remove

public void remove(Event e)
Remove the pending event.


execute

public void execute(Event e)
Execute the event on the event-loop thread; return when completed. If these requests are ongoing then consider creating a dedicated Request object.


remove

private Event remove()
Remove and return the first pending event, or null if there are no pending event. Also set the isGoingToBlock flag (after all with the event queue empty there is nothing better to do).


runEventLoop

private void runEventLoop(boolean pendingOnly)
Run the event-loop. If pendingOnly, stop after processing all pending events. The event loop is stopped by calling requestStop (that stops the event loop once all pending events have been processed). Any existing pending events are always processed before performing the first poll.


requestStop

public void requestStop()
Request that the event-loop stop. The event loop stops once all pending events have been processed. Can be called asynchronously.


runPending

public final void runPending()
Run the event loop until there are no pending events. Of course, if more events are appended to the pending queue, then they too are processed. For testing only. This method does not check for asynchronous events (Signals, Poll, Timers) is made. For that see runPolling.


runPolling

public final boolean runPolling(long timeout)
Run the full event loop (checking for both synchronous and asynchronous events) for at most TIMEOUT milliseconds. Return true if the event loop was stopped before the timer expired. For testing only. Should only be used thus: eventLoop.add<>Event (new <>Event () { public void execute () { eventLoop.stop (); }}); assertTrue ("Waiting for <>", eventLoop.runPolling (<>));


run

public final void run()
Specified by:
run in interface Runnable
Overrides:
run in class Thread

start

public void start()
Start the EventLoop thread; note that this forces a brief synchronization with that thread to ensure that it is ready.

Overrides:
start in class Thread

factory

public static EventLoop factory()
Return the current prefered flavour of the event-loop.