org.erights.e.elib.vat
Class HeadlessRunner

java.lang.Object
  |
  +--org.erights.e.elib.vat.Runner
        |
        +--org.erights.e.elib.vat.HeadlessRunner
All Implemented Interfaces:
Runnable

final class HeadlessRunner
extends Runner
implements Runnable

A redirectable Runner, mostly for internal use.

Author:
Mark S. Miller, Many improvements due to suggestions by E-Dean Tribble

Field Summary
private static int DEQUEUE_GRANULARITY
          The number of Runnables to dequeue and run in one go.
private  FlexSet myDeadManSwitches
          The DeadManSwitches I need to inform if I shutdown.
private  SynchQueue myOptQ
          Where PendingEvents are to be enqueued, or null if I've been redirected.
private  Runner myOptTarget
          The Runner that this Runner has been redirected to, or null if this Runner is fresh.
private  RunnerThread myOptThread
          The RunnerThread servicing this Runner's queue.
private  Object myQLock
          myOptQ's internal lock.
 
Fields inherited from class org.erights.e.elib.vat.Runner
myOptServingVat, myServingTicket
 
Constructor Summary
(package private) HeadlessRunner(String optName)
          Makes a Vat, and starts the thread that services its queue.
 
Method Summary
(package private)  void addDeadManSwitch(Object deadManSwitch)
          Remember the deadManSwitch, so that if I'm shut down, I can notify him.
(package private)  void disturbEvent(Throwable t)
          Performs a Thread.stop(t) on the thread executing the current event.
protected  Throwable enqueue(PendingEvent todo)
          Add todo to the queue my thread is servicing
(package private)  String getRunnerKind()
          What kind of Runner is this?
(package private)  boolean isCurrent()
          Is the current thread this Runner's thread (the thread servicing this Vat)?
(package private)  Runner redirect(Runner newRunner)
          If the enabling conditions are met, then requeue all my events onto newRunner's queue, and remember to redirect all further requests to newRunner.
 void run()
          Called only by Thread.start().
(package private)  void setPriority(int newPriority)
          Requests a change of priority of the thread servicing this Runner.
(package private)  Runner shorten()
          If x.shorten() != x, then this Runner is no more, and should not be used.
 String toString()
          Suppressed: Returns a string representation of the object.
 
Methods inherited from class org.erights.e.elib.vat.Runner
getCurrentRunner, getOptCurrentRunner, getOptEStack, getOptServingVat, obtainRunner, obtainRunner, popEStackItem, pushEStackItem, requireCurrent, servingTicket
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DEQUEUE_GRANULARITY

private static final int DEQUEUE_GRANULARITY
The number of Runnables to dequeue and run in one go. Must be >= 1.


myOptThread

private transient RunnerThread myOptThread
The RunnerThread servicing this Runner's queue.

If we ever go orthogonal again, myOptThread must not be checkpointed. Ie, it must be a DISALLOWED_FIELD or 'transient' or something.


myOptTarget

private Runner myOptTarget
The Runner that this Runner has been redirected to, or null if this Runner is fresh.


myOptQ

private SynchQueue myOptQ
Where PendingEvents are to be enqueued, or null if I've been redirected.

Note that SynchQueue is a thread-safe data structure with its own lock which we hold in myQLock.


myQLock

private final Object myQLock
myOptQ's internal lock.


myDeadManSwitches

private FlexSet myDeadManSwitches
The DeadManSwitches I need to inform if I shutdown.

Constructor Detail

HeadlessRunner

HeadlessRunner(String optName)
Makes a Vat, and starts the thread that services its queue.

Parameters:
optName - is the name to give to the created thread.
Method Detail

toString

public String toString()
Description copied from class: Object
Suppressed: Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

 getClass().getName() + '@' + Integer.toHexString(hashCode())
 

Overrides:
toString in class Object
Returns:
a string representation of the object.

shorten

Runner shorten()
Description copied from class: Runner
If x.shorten() != x, then this Runner is no more, and should not be used. This can happen only to HeadlessRunners.

Overrides:
shorten in class Runner
Returns:
The best Runner to use in lieu of me

getRunnerKind

String getRunnerKind()
Description copied from class: Runner
What kind of Runner is this?

A kind of Runner determines which kind of "devices" (eg, AWT or SWT widgets) may be synchronously accessed from within this Runner

Specified by:
getRunnerKind in class Runner
Returns:
"headless"

enqueue

protected Throwable enqueue(PendingEvent todo)
Description copied from class: Runner
Add todo to the queue my thread is servicing

Specified by:
enqueue in class Runner

setPriority

void setPriority(int newPriority)
Description copied from class: Runner
Requests a change of priority of the thread servicing this Runner.

Specified by:
setPriority in class Runner

disturbEvent

void disturbEvent(Throwable t)
Description copied from class: Runner
Performs a Thread.stop(t) on the thread executing the current event.

Note that Thread.stop() does not stop the thread (obvious huh?), but rather causes that thread to experience a "spontaneously" thrown exception.

Specified by:
disturbEvent in class Runner

isCurrent

boolean isCurrent()
Description copied from class: Runner
Is the current thread this Runner's thread (the thread servicing this Vat)?

If it is, we say we are executing inside this Runner.

r.isCurrent() implies Runner.getCurrentRunner() == r.

Specified by:
isCurrent in class Runner

run

public void run()
Called only by Thread.start().

(XXX It's a modularity bug for this to be public.) Pulls PendingEvents from the queue until there aren't any more, then waits until there's more to do.

Specified by:
run in interface Runnable
See Also:
java.lang.Thread#run()

redirect

Runner redirect(Runner newRunner)
If the enabling conditions are met, then requeue all my events onto newRunner's queue, and remember to redirect all further requests to newRunner.

The enabling conditions are

XXX Should we instead have an operation that only requeues the events queued by a given Vat, allowing Vats to migrate rather than merge?


addDeadManSwitch

void addDeadManSwitch(Object deadManSwitch)
Description copied from class: Runner
Remember the deadManSwitch, so that if I'm shut down, I can notify him.

The deadManSwitch is only notified if it's be a boot-ref (a Ref handled by a BootRefHandler whose target's vat is a vat handled by a different Runner. Otherwise, the notification would need to occur in this Runner, which is presumably already shut down.

Specified by:
addDeadManSwitch in class Runner


comments?