org.erights.e.elib.ref
Class StemCell

java.lang.Object
  |
  +--org.erights.e.elib.ref.Ref
        |
        +--org.erights.e.elib.ref.StemCell
All Implemented Interfaces:
Amplifiable, Callable, Marker, ObjectInputValidation, PassByConstruction, Persistent, Serializable
Direct Known Subclasses:
RemoteCall, RemoteDelivery

public class StemCell
extends Ref
implements PassByConstruction, Persistent, ObjectInputValidation

Untamed: An object can writeReplace itself with a StemCell when serialized in order to resolve to the StemCell's readResolve, but with circular references handled as correctly as possible.

A known problem with Java Unserialization is that a circular reference to an encoded object A may get bound to A itself rather than what A readResolves to. For statically typed circular references, or circular references that are synchronously used before the cycle is closed, there's nothing we can do about this other than fail safely (which, unlike raw Java serialization, we do).

For the sake of other circular references, an unserialized StemCell starts as a promise for what it will readResolve to. Once it readResolves, the promise is also resolved, so further references encoded as references to the StemCell will be decoded as this resolution.

On the encoding side, a made StemCell (as opposed to an unserialized StemCell) is a very weird creature. It appears to be an eventual resolved reference (a far reference), but will not deliver any messages, since the object it designates doesn't exist until the StemCell is unserialized. By the same token, we did not make it appear to be a broken reference, because it will become a live reference to the object it makes once it's unserialized. In any case, a made Stem should only be used for an object to instruct its serializer on how to encode it.

XXX StemCell should be declared abstract, but this is commented out in order to work around a bug in Sun's j2sdk1.4.1's javac compiler.

Author:
Mark S. Miller
See Also:
Serialized Form

Field Summary
private  Ref myOptPromise
          null on the encoding side for a made StemCell.
protected  Resolver myOptResolver
          Subclasses must define a readResolve() that both returns the resolution of the StemCell, and resolves this resolver to that resolution.
private static long serialVersionUID
           
 
Fields inherited from class org.erights.e.elib.ref.Ref
BROKEN, EVENTUAL, NEAR, TheViciousRef
 
Fields inherited from interface org.erights.e.elib.serial.PassByConstruction
HONORARY, HONORED_NAMES
 
Fields inherited from interface org.erights.e.elib.serial.Persistent
HONORARY, HONORED_NAMES
 
Constructor Summary
protected StemCell()
          Makes a made StemCell
 
Method Summary
 Object callAll(String verb, Object[] args)
          Suppressed:
(package private)  void commit()
          Used by a resolvers to turn off switchability, and thereby make this Ref equivalent to its current target.
 boolean isResolved()
          Suppressed: A made StemCell is resolved, and so appears to be a far ref.
 Throwable optProblem()
          Suppressed: A made StemCell returns null; an unserialized one returns its promise's problem.
private  void readObject(ObjectInputStream ois)
          Initializes the promise, does the default thing, and then resolves to the result of readResolve(), to be provided by a subclass.
(package private)  Ref resolutionRef()
          A made StemCell's resolution is itself.
 Ref sendAll(String verb, Object[] args)
          Suppressed:
 Throwable sendAllOnly(String verb, Object[] args)
          Suppressed:
(package private)  void setTarget(Ref newTarget)
          Used by a resolvers to change the target.
 String state()
          Suppressed: A made StemCell returns EVENTUAL, and unserialized one returns what its promise returns.
 void validateObject()
          Suppressed:
 
Methods inherited from class org.erights.e.elib.ref.Ref
broken, disconnected, getAllegedType, getOptProxyHandler, GetRefMaker, ignore, isBroken, isDeepFrozen, isDeepPassByCopy, isEventual, isFar, isNear, isPassByProxy, isPBC, isPersistent, isResolved, isSameEver, isSelfish, isSelfless, isSettled, makeBufferingPromise, makeSwitchablePromise, optBroken, optProblem, optSealedDispatch, optSealedDispatch, optShorten, promise, resolution, resolution, respondsTo, sendMsg, state, toCallable, toRef, toString, whenBroken, whenBrokenOnly, whenResolved, whenResolvedOnly
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

serialVersionUID

private static final long serialVersionUID

myOptPromise

private transient Ref myOptPromise
null on the encoding side for a made StemCell. Unresolved during the unserializing of the StemCell itself. Resolved to the StemCell's resolution once the StemCell is fully unserialized.


myOptResolver

protected transient Resolver myOptResolver
Subclasses must define a readResolve() that both returns the resolution of the StemCell, and resolves this resolver to that resolution.

Constructor Detail

StemCell

protected StemCell()
Makes a made StemCell

Method Detail

readObject

private void readObject(ObjectInputStream ois)
                 throws ClassNotFoundException,
                        IOException
Initializes the promise, does the default thing, and then resolves to the result of readResolve(), to be provided by a subclass.

ClassNotFoundException
IOException

optProblem

public Throwable optProblem()
Suppressed: A made StemCell returns null; an unserialized one returns its promise's problem.

All implementations of optProblem/0 must be thread safe, in order for Ref.state/0 to be thread safe.

Specified by:
optProblem in class Ref
See Also:
Ref.optProblem(Object)

resolutionRef

Ref resolutionRef()
A made StemCell's resolution is itself. An unserialized one's is according to its promise.

All implementations of resolutionRef/0 must be thread safe, in order for Ref.resolution/0 to be thread safe: myOptPromise is not meaningfully mutable, so this implementation is trivially inductively thread safe.

Specified by:
resolutionRef in class Ref

state

public String state()
Suppressed: A made StemCell returns EVENTUAL, and unserialized one returns what its promise returns.

All implementations of state/0 must be thread safe, in order for Ref.isNear/1 to be thread safe.

Overrides:
state in class Ref
See Also:
Ref.state(Object)

callAll

public Object callAll(String verb,
                      Object[] args)
Suppressed:

Specified by:
callAll in interface Callable
Specified by:
callAll in class Ref

sendAll

public Ref sendAll(String verb,
                   Object[] args)
Suppressed:

Specified by:
sendAll in class Ref

sendAllOnly

public Throwable sendAllOnly(String verb,
                             Object[] args)
Suppressed:

Specified by:
sendAllOnly in class Ref
Returns:
Why wasn't this event queued? It isn't queued if this vat or comm connection is shut down, in which case the returned problem explains why. If null is returned, then the event was queued, though it may still not arrive.

isResolved

public boolean isResolved()
Suppressed: A made StemCell is resolved, and so appears to be a far ref.

Specified by:
isResolved in class Ref

setTarget

void setTarget(Ref newTarget)
Description copied from class: Ref
Used by a resolvers to change the target. If newTarget is equivalent to this Ref, then this Ref becomes broken by a ViciousCycleException.

Specified by:
setTarget in class Ref

commit

void commit()
Description copied from class: Ref
Used by a resolvers to turn off switchability, and thereby make this Ref equivalent to its current target.

If the current target is already equivalent to this Ref, then this Ref becomes broken by a ViciousCycleException.

Specified by:
commit in class Ref

validateObject

public void validateObject()
                    throws InvalidObjectException
Suppressed:

Specified by:
validateObject in interface ObjectInputValidation
Throws:
InvalidObjectException


comments?