|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--org.erights.e.elib.vat.Vat
Untamed: A Vat is a disjoint partitioning of objects.
Each object should ideally be associated with exactly one Vat, and should
only be invoked inside that Vat. However, since it would be too costly to
add a Vat field to all objects, rather, the object's Vat context is
restored prior to invoking the object. This context is captured on
enqueueing a message for the object (or enqueueing any other
PendingEvent
). These events are enqueued onto the event loop of
a Runner
, which manages the dequeueing. There can be multiple Vats
per Runner.
When Vat x is merged into
Vat y, this
means that both x and y will then be served by the Runner
that was serving y.
Field Summary | |
private boolean |
myIsMergeable
Can I still merge? |
private long |
myNextTicket
The ticket number to be "dispensed" to the next enqueued Runnable. |
private String |
myOptName
For debugging. |
private Runner |
myRunner
Should only be used by getRunner(), so that everyone will get the current Runner. |
Constructor Summary | |
private |
Vat(Runner runner,
boolean mergeable,
String optName)
|
Method Summary | |
Object |
callAll(Object rec,
String verb,
Object[] args)
Enabled: Wraps E.callAll(rec, verb, args) to ensure we're executing using this Vat. |
Throwable |
enqueue(Runnable todo)
Enabled: Enqueue's something for this Runnable's thread to do. |
static Vat |
getCurrentVat()
Enabled: If called from within a thread servicing a Vat, returns that Vat; otherwise, throws an exception. |
static Vat |
getOptCurrentVat()
Enabled: If called from within a thread servicing a Vat, returns that Vat; otherwise null. |
(package private) Runner |
getRunner()
This returns the current Runner for this Vat, but beware that this may change over time as a result of merging . |
String |
getRunnerKind()
Enabled: May be called from any thead. |
Object |
invoke(Object obj,
java.lang.reflect.Method method,
Object[] args)
Enabled: Wraps method.invoke(obj, args) to ensure we're executing using this Vat. |
boolean |
isCurrent()
Enabled: Is the current event within this Vat? |
boolean |
isCurrentRunner()
Enabled: May be called from any thead. |
static Vat |
make(String runnerKind)
Enabled: optName defaults to null |
static Vat |
make(String runnerKind,
String optName)
Enabled: Makes a Vat onto an obtained Runner of the
specified kind. |
Ref |
mergeInto(Vat other)
Enabled: If this Vat can still merge, it should eventually merge itself into other's Runner. |
Ref |
morphInto(String runnerKind)
Enabled: optName defaults to null |
Ref |
morphInto(String runnerKind,
String optName)
Enabled: Like mergeInto(org.erights.e.elib.vat.Vat) , but merges into a kind of Runner rather than
the Runner of a pre-existing Vat. |
void |
now(Runnable todo)
Enabled: Schedules a Runnable to execute in a Runner (in the Runner's thread as a separate turn), while also effectively executing as a synchronous call within the requestors's external thread . |
Ref |
orderlyShutdown(Throwable problem)
Enabled: Requests this vat to eventually shut down once all already queued events have been processed. |
Ref |
qSendAll(Object rec,
boolean nowFlag,
String verb,
Object[] args)
Enabled: Enqueues a 'rec <- verb(args...)' and returns a promise for the result. |
Throwable |
qSendAllOnly(Object rec,
boolean nowFlag,
String verb,
Object[] args)
Enabled: Enqueues a 'rec <- verb(args...)' when no conventional result is needed. |
Throwable |
qSendMsg(Object rec,
Message msg)
Enabled: Enqueues the delivery of msg to rec. |
void |
requireCurrent()
Enabled: If not isCurrent() , throw an exception. |
static void |
requireExternal()
Enabled: If the current thread isn't an external thread , throws an
exception. |
void |
requireKind(String runnerKind)
Enabled: Requires getRunnerKind() to be runnerKind |
Ref |
seed(Object rec)
Enabled: The message defaults to ' <- run()'. |
Ref |
seed(Object rec,
String verb,
Object[] args)
Enabled: Seeds initial computation in a vat and communications between vats. |
static Ref |
sendAll(Object rec,
String verb,
Object[] args)
Enabled: Queue the sendAll in the current vat. |
static Throwable |
sendAllOnly(Object rec,
String verb,
Object[] args)
Enabled: Queue the sendAllOnly in the current vat. |
void |
setPriority(int newPriority)
Enabled: May be called from any thead. |
Vat |
sprout(String optName)
Enabled: Returns new Vat sharing my Runner. |
(package private) long |
takeTicket()
Dispenses a ticket number for the next enqueued Runnable. |
String |
toString()
Suppressed: May be called from any thead. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
private Runner myRunner
private boolean myIsMergeable
private long myNextTicket
Ie, the ticket number that will be being served when this next Runnable will be run(). May be used for causality tracing.
private final String myOptName
Constructor Detail |
private Vat(Runner runner, boolean mergeable, String optName)
Method Detail |
public static Vat make(String runnerKind)
May be called from any thead.
make(String, String)
public static Vat make(String runnerKind, String optName)
obtained
Runner of the
specified kind.
May be called from any thead.
runnerKind
- says which kind
of
Runner to make.optName
- If we are making a new Runner, the name is also used to
tag it and its thread for debugging purposes.public static Vat getOptCurrentVat()
May be called from any thead.
public static Vat getCurrentVat()
May be called from any thead.
public static void requireExternal()
external thread
, throws an
exception.
public static Throwable sendAllOnly(Object rec, String verb, Object[] args)
public static Ref sendAll(Object rec, String verb, Object[] args)
public String toString()
toString
in class Object
Runner getRunner()
merging
.
public boolean isCurrent()
If it is, we say we are executing inside this Vat.
v.isCurrent() implies
getCurrentVat()
== v.
May be called from any thead.
public void requireCurrent()
isCurrent()
, throw an exception.
May be called from any thead.
public String getRunnerKind()
Runner.getRunnerKind()
public void requireKind(String runnerKind)
getRunnerKind()
to be runnerKind
public boolean isCurrentRunner()
Runner.isCurrent()
public void setPriority(int newPriority)
Runner.setPriority(int)
long takeTicket()
Ie, the ticket number that will be being served when this next Runnable will be run(). May be used for causality tracing.
Ticket counts are incremented separately per Vat rather than per Runner, and so must be understood relative to the enqueueing Vat.
public Ref seed(Object rec, String verb, Object[] args)
Use for bootstrapping to boot-comm-system. This is an inherently
dangerous operation -- use only if you know what you're doing; do not
provide this ability directly to untrusted code. Most code should
instead the emaker org.erights.e.elang.interp.seedVatAuthor
.
While treating rec as if it were a member of this vat, seed will enqueue a
rec <- verb(args...)to occur in this vat and return a promise for the result, just as if rec were a proper boot-ref to an object already in this vat, and the above message had simply been sent from the current vat on this boot-ref. In particular, the treatment of the arguments and return result is exactly according to this story. The only cheating is in regards to rec itself. As with
BootShuttle
, this is
safe only when all the mutable state transitively reachable from
rec is no longer reachable from any other vat (typically,
not from the current vat -- the vat of origin), or that any possibly
shared mutable state is managed in a conventionally thread-safe manner.
This is typically used by having computation in the current vat create
a thunk (a non-argument function) that, when invoked, creates the
mutable state for a new service, and creates and returns the new
service in the scope of that mutable state. The caller of seed
in the current vat then has a boot-ref to the new service, which is
executing in this vat. For this specific pattern, the
seed/1
function is provided as a convenience.
Once we have auditors working, then we may provide a safe form of these operations that only accept DeepFrozen objects as rec.
public Ref seed(Object rec)
seed(Object, String, Object[])
public Throwable enqueue(Runnable todo)
May be called from any thead.
public Throwable qSendMsg(Object rec, Message msg)
The sending context is the sending context captured in msg.
May be called from any thead.
XXX to be made non-public. Uses outside this package should use
boot-refs
instead.
public Throwable qSendAllOnly(Object rec, boolean nowFlag, String verb, Object[] args)
May be called from any thead.
XXX to be made non-public. Uses outside this package should use
boot-refs
instead.
public Ref qSendAll(Object rec, boolean nowFlag, String verb, Object[] args)
If this vat is shut down, the returned reference is immediately broken (by a complaint explaining why). Otherwise, if it becomes known that this event might never be delivered, then the reference eventually becomes broken with a complaint explaining why.
May be called from any thead.
XXX to be made non-public. Uses outside this package should use
boot-refs
instead.
public void now(Runnable todo)
external thread
.
Note: As of 0.8.20, we require that the caller's thread be external,
in order to avoid a deadlock danger created by mergeInto(org.erights.e.elib.vat.Vat)
. The
danger is that if we allow Runner x to block waiting on Runner y, then
if y is redirected to x (if y's Vat is mergedInto one of x's Vats),
then x would then be waiting on x. The old guard test to check if the
caller is in the same Runner as the callee doesn't help, since that
test says they are different prior to x blocking.
In most ways this can be thought of as a symmetric rendezvous between
the calling external thread and the callee Runner thread. The reason
we specify that the Runnable is executed specifically in the
callee's Vat (and its associated Runner and thread) is so that
thread-scoped state (such as getCurrentVat()
will be according
to the callee's Vat.
If todo throws a problem rather than successfully returning, then now() rethrows that problem as well.
If this vat is shut down, or shuts down before todo is executed, then a complaint about that is thrown and 'todo' is never executed.
May be called from any
external thread
.
public Object invoke(Object obj, java.lang.reflect.Method method, Object[] args) throws IllegalAccessException, java.lang.reflect.InvocationTargetException
Must be called from within this Runner, and either within this Vat, or between PendingEvents of this Runner. In the latter case, this invocation becomes like a PendingEvent, but with a ticket count of -1.
IllegalAccessException
java.lang.reflect.InvocationTargetException
callAll/3
public Object callAll(Object rec, String verb, Object[] args)
Must be called from within this Runner, and either within this Vat, or between PendingEvents of this Runner. In the latter case, this invocation becomes like a PendingEvent, but with a ticket count of -1.
invoke/3
public Vat sprout(String optName)
The new Vat isn't mergeable whether or not I am. This makes
def v2 := v1.sprout("foo")like
def v2 := vatMaker.make("headless", "foo") v2.mergeInto(v1)except that it's as if the merge happens immediately.
May be called from any thead.
public Ref mergeInto(Vat other)
If the redirect attempt succeeds, it transfers the ability to redirect this Vat further to the other Vat. Likewise, when this Vat is redirected, all events queued by this Vat and any Vat that has merged into this Vat are merged into the other Vat, since these earlier Vats have transfered their merging power to this Vat.
XXX It is unclear whether this is the right abstraction, or whether we should instead provide a migrate operation that requeues just the events queued by a given Vat. Currently, we choose mergeInto, since it has a simpler implementation -- just migrate an entire HeadlessRunner's queue and shut down its thread.
May be called from any thead.
public Ref orderlyShutdown(Throwable problem)
A shutdown does a merge into a DeadRunner
.
May be called from any thead.
mergeInto(org.erights.e.elib.vat.Vat)
public Ref morphInto(String runnerKind)
May be called from any thead.
morphInto(String, String)
public Ref morphInto(String runnerKind, String optName)
mergeInto(org.erights.e.elib.vat.Vat)
, but merges into a kind of Runner rather than
the Runner of a pre-existing Vat.
This is just an optimization, as
v1.morphInto("awt")is equivalent to
def v2 := vatMaker.make("awt") v1.mergeInto(v2)but without bothering to create v2.
May be called from any thead.
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |