[e-cvs] cvs commit: e/src/jsrc/org/erights/e/meta/java/io FileSugar.java InputStreamSugar.java

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Mon, 20 Aug 2001 01:07:44 -0400


markm       01/08/20 01:07:44

  Modified:    src/esrc/org/erights/e/elang/cmd cmdLoopMakerAuthor.emaker
                        cmdLoopMakerAuthor.updoc cmdMakerMaker.updoc
               src/esrc/scripts echat.e
               src/jsrc/net/captp/jcomm Sturdifier.java
               src/jsrc/net/vattp/data DataPath.java SendThread.java
               src/jsrc/net/vattp/tunnel HTTPSocketCtl.java
               src/jsrc/org/erights/e/elib/prim MirandaMethods.java
                        Queue.java Runner.java StaticMaker.java
               src/jsrc/org/erights/e/elib/tables ConstMap.java
               src/jsrc/org/erights/e/extern/timer TimerThread.java
               src/jsrc/org/erights/e/meta/java/io FileSugar.java
                        InputStreamSugar.java
  Added:       src/esrc/org/erights/e/elang/cmd controlLoopMaker.emaker
                        controlLoopMaker.updoc
               src/esrc/scripts evalServer.e evalServer.updoc
  Removed:     src/esrc/org/erights/e/elang/cmd
                        controlLoopMakerAuthor.emaker
                        controlLoopMakerAuthor.updoc
  Log:
  evalServer.e looks pretty good

Revision  Changes    Path
1.4       +2 -2      e/src/esrc/org/erights/e/elang/cmd/cmdLoopMakerAuthor.emaker

Index: cmdLoopMakerAuthor.emaker
===================================================================
RCS file: /cvs/e/src/esrc/org/erights/e/elang/cmd/cmdLoopMakerAuthor.emaker,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- cmdLoopMakerAuthor.emaker	2001/08/19 06:35:55	1.3
+++ cmdLoopMakerAuthor.emaker	2001/08/20 05:07:43	1.4
@@ -1,8 +1,8 @@
 def cmd__uriGetter := <import:org.erights.e.elang.cmd.*>
 def propUtils := <import:org.erights.e.tools.collect.propUtils>
+def controlLoopMaker := <cmd:controlLoopMaker>
 
-def cmdLoopMakerAuthor(QueueMaker, SystemGC) :any {
-    def controlLoopMaker := <cmd:controlLoopMakerAuthor>(QueueMaker)
+def cmdLoopMakerAuthor(SystemGC) :any {
     
     class cmdLoopMaker(args, props, topScope) :any {
 



1.2       +2 -5      e/src/esrc/org/erights/e/elang/cmd/cmdLoopMakerAuthor.updoc

Index: cmdLoopMakerAuthor.updoc
===================================================================
RCS file: /cvs/e/src/esrc/org/erights/e/elang/cmd/cmdLoopMakerAuthor.updoc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- cmdLoopMakerAuthor.updoc	2001/08/16 07:05:38	1.1
+++ cmdLoopMakerAuthor.updoc	2001/08/20 05:07:43	1.2
@@ -1,9 +1,6 @@
     ? def cmd__uriGetter := <import:org.erights.e.elang.cmd.*>
     # value: <import:org.erights.e.elang.cmd.*>
     
-    ? def QueueMaker := <unsafe:org.erights.e.elib.prim.Queue>
-    # value: <unsafe:org.erights.e.elib.prim.Queue>
-    
     ? def SystemGC {
     >     to gc() {
     >         println("System.gc()")
@@ -12,7 +9,7 @@
     > }
     # value: <SystemGC>
     
-    ? def cmdLoopMaker := <cmd:cmdLoopMakerAuthor>(QueueMaker, SystemGC)
+    ? def cmdLoopMaker := <cmd:cmdLoopMakerAuthor>(SystemGC)
     # value: <cmdLoopMaker>
     
     ? def ScopeImplMaker := <unsafe:org.erights.e.elang.scope.ScopeImpl>
@@ -73,4 +70,4 @@
     #   <cmdLoop> getResult(0)
     #   <interactive interp> evalPrint(e`cmdLoop getResult(0)`)
     
-    ? 
\ No newline at end of file
+    ? 



1.4       +2 -5      e/src/esrc/org/erights/e/elang/cmd/cmdMakerMaker.updoc

Index: cmdMakerMaker.updoc
===================================================================
RCS file: /cvs/e/src/esrc/org/erights/e/elang/cmd/cmdMakerMaker.updoc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- cmdMakerMaker.updoc	2001/08/19 06:35:55	1.3
+++ cmdMakerMaker.updoc	2001/08/20 05:07:43	1.4
@@ -7,9 +7,6 @@
     ? def cmdMakerMaker := <cmd:cmdMakerMaker>
     # value: <cmdMakerMaker>
     
-    ? def QueueMaker := <unsafe:org.erights.e.elib.prim.Queue>
-    # value: <unsafe:org.erights.e.elib.prim.Queue>
-    
     ? def SystemGC {
     >     to gc() {
     >         println("System.gc()")
@@ -18,7 +15,7 @@
     > }
     # value: <SystemGC>
     
-    ? def cmdLoopMaker := <cmd:cmdLoopMakerAuthor>(QueueMaker, SystemGC)
+    ? def cmdLoopMaker := <cmd:cmdLoopMakerAuthor>(SystemGC)
     # value: <cmdLoopMaker>
     
     ? def ScopeSetup := <unsafe:org.erights.e.elang.interp.ScopeSetup>
@@ -95,4 +92,4 @@
     #        \n\
     #        "
     
-    ? 
\ No newline at end of file
+    ? 



1.1                  e/src/esrc/org/erights/e/elang/cmd/controlLoopMaker.emaker

Index: controlLoopMaker.emaker
===================================================================
def QueueMaker := <import:org.erights.e.elib.prim.Queue>

class controlLoopMaker() :any {

    # Should we block between turns?
    var myShouldBlock := false

    # Is there a 'internalLoop <- ()' in the air?
    var myIsAlarmSet := false

    # A pair of an exit-code and an optional problem.
    # If non-null, we *should* exit.
    var myOptExitPair := null
    def [myExitPairVow, myExitPairResolver] := PromiseMaker()

    # A queue of Runnables to run in order, each in their own
    # turn.  If null, we *have* exitted.
    var myOptQueue := QueueMaker new()

    var servingTicket := 0
    var nextTicket := 1

    def myStatusReactors := [] diverge()

    def notifier {
        match [verb, args] {
            for reactor in myStatusReactors {
                E sendOnly(reactor, verb, args)
            }
        }
    }

    def internalLoop
    def controlLoop

    # Make sure we're going to wake up if we should
    def setAlarm() {
        if (! myIsAlarmSet && ! myShouldBlock && myOptQueue != null) {
            myIsAlarmSet := true
            internalLoop <- ()
        }
    }

    def bind internalLoop() {
        myIsAlarmSet := false
        if (myShouldBlock) {
            # do nothing
            notifier reactToBlock(servingTicket)
        } else if (myOptExitPair != null) {
            myOptQueue := null
            myExitPairResolver resolve(myOptExitPair)
            notifier reactToExit(servingTicket, myOptExitPair[0], myOptExitPair[1])
        } else if (myOptQueue optDequeue() =~ runnable ? (runnable != null)) {
            servingTicket += 1
            try {
                runnable()
                notifier reactToSuccess(servingTicket, myShouldBlock)
            } catch problem {
                controlLoop exitAtTop(-1, problem)
            }
            setAlarm()
        } else {
            notifier reactToQueueEmpty(servingTicket)
            # queue is empty, do nothing
        }
    }

    def bind controlLoop {
        to blockAtTop() {
            if (myOptExitPair == null) {
                # Don't block if we should exit.  We won't execute any more
                # runnables anyway.
                myShouldBlock := true
            }
        }
        to continueAtTop() {
            myShouldBlock := false
            setAlarm()
        }
        to waitAtTop(ref) {
            controlLoop blockAtTop()
            def done(_) {
                controlLoop continueAtTop()
            }
            Ref whenResolved(ref, done)
        }
        to exitAtTop() {
            controlLoop exitAtTop(0, null)
        }
        to exitAtTop(exitCode, optProblem) {
            myOptExitPair := [exitCode, optProblem]
            myShouldBlock := false
            setAlarm()
        }
        to enqueue(runnable) {
            if (myOptQueue != null) {
                myOptQueue enqueue(runnable)
                setAlarm()
            }
            notifier reactToEnqueue(nextTicket)
            nextTicket += 1
        }
        # Returns a pair of an exit code and an optional problem.
        # Normally, an exit code of zero should have no problem
        # whereas any other exit code should have a problem, but
        # this is not enforced.  XXX It probably should be and
        # will be enforced.
        to getExitPairVow() :any {
            myExitPairVow
        }
        to addStatusReactor(reactor) {
            myStatusReactors push(reactor)
        }
    }
}





1.1                  e/src/esrc/org/erights/e/elang/cmd/controlLoopMaker.updoc

Index: controlLoopMaker.updoc
===================================================================
    ? def cmd__uriGetter := <import:org.erights.e.elang.cmd.*>
    # value: <import:org.erights.e.elang.cmd.*>
    
    ? def controlLoopMaker := <cmd:controlLoopMaker>
    # value: <controlLoopMaker>
    
    ? def reactor {
    >     match [verb, args] {
    >         println(`$verb$args`)
    >     }
    > }
    # value: <reactor>
    
    ? def ctrl := controlLoopMaker new()
    # value: <controlLoop_7>
    
    ? ctrl addStatusReactor(reactor)
    ? ctrl enqueue(thunk{println("foo")})
    ? 
    foo
    reactToEnqueue[1]
    reactToSuccess[1, false]
    reactToQueueEmpty[1]
    ? (ctrl enqueue(thunk{println("bar")})
    >  ctrl blockAtTop()
    >  ctrl enqueue(thunk{println("baz")})
    > )
    ? 
    reactToEnqueue[2]
    reactToEnqueue[3]
    reactToBlock[1]
    ? ctrl continueAtTop()
    ? 
    bar
    reactToSuccess[2, false]
    baz
    reactToSuccess[3, false]
    reactToQueueEmpty[3]
    ? def [p,r] := PromiseMaker()
    # value: [<Eventual ref>, <Open Resolver>]
    
    ? def event() {
    >     println("before")
    >     println("after")
    >     ctrl enqueue(thunk{println("next")})
    >     ctrl waitAtTop(p)
    > }
    # value: <event>
    
    ? ctrl enqueue(event)
    ? 
    before
    after
    reactToEnqueue[4]
    reactToEnqueue[5]
    reactToSuccess[4, true]
    reactToBlock[4]
    ? 
    ? r resolve(3)
    ? 
    next
    reactToSuccess[5, false]
    reactToQueueEmpty[5]
    ? def exitPairVow := ctrl getExitPairVow()
    # value: <Eventual ref>
    
    ? exitPairVow
    # value: <Eventual ref>
    
    ? def event2() {
    >     ctrl exitAtTop()
    >     println(`exit: ${ctrl getExitPairVow()}`)
    >     ctrl enqueue(thunk{println("already dead")})
    > }
    # value: <event2>
    
    ? ctrl enqueue(event2)
    ? 
    exit: <Eventual ref>
    reactToEnqueue[6]
    reactToEnqueue[7]
    reactToSuccess[6, false]
    reactToExit[6, 0, null]
    ? 
    ? exitPairVow
    # value: [0, null]
    
    ? def ctrl3
    # value: <Eventual ref>
    
    ? def event3() {
    >     println("before")
    >     println("after")
    >     ctrl3 enqueue(thunk{println("next")})
    >     ctrl3 blockAtTop()
    > }
    # value: <event3>
    
    ? def bind ctrl3 := controlLoopMaker new()
    # value: <controlLoop_7>
    
    ? ctrl3 addStatusReactor(reactor)
    ? ctrl3 enqueue(event3)
    ? 
    before
    after
    reactToEnqueue[1]
    reactToEnqueue[2]
    reactToSuccess[1, true]
    reactToBlock[1]
    ? def exitPairVow3 := ctrl3 getExitPairVow()
    # value: <Eventual ref>
    
    ? exitPairVow3
    # value: <Eventual ref>
    
    ? ctrl3 exitAtTop()
    ? 
    reactToExit[1, 0, null]
    ? 
    ? exitPairVow3
    # value: [0, null]
    
    ? 






1.12      +36 -9     e/src/esrc/scripts/echat.e

Index: echat.e
===================================================================
RCS file: /cvs/e/src/esrc/scripts/echat.e,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- echat.e	2001/07/31 13:09:14	1.11
+++ echat.e	2001/08/20 05:07:43	1.12
@@ -38,18 +38,44 @@
     "EChat"
 }
 
-introducer onTheAir()
+def ser__uriGetter := <unsafe:org.erights.e.elib.serial.*>
+def SerializerMaker := <ser:Serializer>
+def UnserializerMaker := <ser:Unserializer>
+
+def chatReceiver
+def sturdyChatReceiver
+
+if (interp getArgs() =~ [=="-save", filename]) {
+    traceln("first incarnation")
+    def keyPair := introducer newVatIdentity()
+    introducer onTheAir()
+    def netConfig := introducer getNetConfig()
+    def [bind sturdyChatReceiver, swissBase] := sturdyRef incarnate(chatReceiver)
+    def file := <file: filename>
+    SerializerMaker recordFile(file, [netConfig, keyPair, swissBase])
+
+} else if (interp getArgs() =~ [=="-restore", filename]) {
+    traceln("reincarnation")
+    def file := <file: filename>
+    require(file exists())
+    def [netConfig, keyPair, swissBase] := UnserializerMaker playFile(file)
+    introducer setNetConfig(netConfig)
+    introducer setVatIdentity(keyPair)
+    introducer onTheAir()
+    def bind sturdyChatReceiver := sturdyRef reincarnate(chatReceiver, swissBase)
+} else {
+    traceln("once only incarnation")
+    introducer onTheAir()
+    def bind sturdyChatReceiver := sturdyRef(chatReceiver)
+}
 traceln(introducer)
+traceln(sturdyChatReceiver)
 
 # return the object represented by the URI
 def getObjectFromURI(uri) :any {
     introducer sturdyFromURI(uri) promiseRef()
 }
 
-def makeURIFromObject(obj) :any {
-    introducer sturdyToURI(sturdyRef(obj))
-}
-
 # return the friend file
 def findFriendFile(chatWin) :any {
     def dialog := <awt:FileDialog> new(chatWin, "Select a Friend")
@@ -77,6 +103,7 @@
 # method that writes out the URI for your echat system's communication
 # interface
 def offerMyAddress(file, uri) {
+    traceln(`$file setText("$uri")`)
     file setText(uri)
 }
 
@@ -175,7 +202,7 @@
 # facet of chatController sent to other chatter with only appropriate
 # messages
 class chatReceiverMaker(var chatController) :any {
-    def chatReceiver {
+    def bind chatReceiver {
         to receive(message) { chatController receive(message) }
         to receiveFriend(friend, name) :any {
             chatController receiveFriend(friend, name)
@@ -198,7 +225,7 @@
             chatUI getChatTextArea() append(senderName +" says:\t"+ message + "\n")
         }
         def showDebug(message) {
-            chatUI getChatTextArea() append("Debug: " + message + "\n")
+            # chatUI getChatTextArea() append("Debug: " + message + "\n")
         }
         def chatController {
             # transmitting functions
@@ -224,8 +251,8 @@
             to offerSelf() {
                 myAddressFile := requestSaveFile(chatUI getChatWin())
                 if (myAddressFile != null) {
-                    offerMyAddress(myAddressFile,
-                    makeURIFromObject(myChatReceiver))
+                    def uri := introducer sturdyToURI(sturdyChatReceiver)
+                    offerMyAddress(myAddressFile, uri)
                 }
             }
             to leave() {



1.1                  e/src/esrc/scripts/evalServer.e

Index: evalServer.e
===================================================================
def TextWriterMaker := <import:org.erights.e.elib.base.TextWriter>
def cmd__uriGetter := <import:org.erights.e.elang.cmd.*>
def cmdMakerMaker := <cmd:cmdMakerMaker>
def SystemGC {
    to gc() {
        println("System.gc()")
        <unsafe:java.lang.System> gc()
    }
}
def cmdLoopMaker := <cmd:cmdLoopMakerAuthor>(SystemGC)
def ScopeSetup := <unsafe:org.erights.e.elang.interp.ScopeSetup>

def evalServer {
    to newScriptEvaluator(args) :any {

        def [altout, altoutBuf] := TextWriterMaker makeBufferingPair()
        def [alterr, alterrBuf] := TextWriterMaker makeBufferingPair()

        def cmdLoop
        # XXX What properties should we use?
        def props := interp getProps()
        def privileged := ScopeSetup privileged(
            true,
            altout,
            alterr,
            props,
            cmdLoop)
        def bind cmdLoop := cmdLoopMaker new(args, props, privileged)
        def cmdMaker := cmdMakerMaker new(cmdLoop, altoutBuf, alterrBuf)

        def scriptEvaluator {
            to evalCmdVow(sourceCode) :any {
                def [reportVow, cmd] := cmdMaker new(sourceCode)
                cmdLoop enqueue(cmd)
                reportVow
            }
            to getCmdLoop() :any { cmdLoop }
        }
    }
}
introducer onTheAir()
def sr := sturdyRef(evalServer)
def uri := introducer sturdyToURI(sr)
println(uri)
uri





1.1                  e/src/esrc/scripts/evalServer.updoc

Index: evalServer.updoc
===================================================================
? introducer onTheAir()
# value: ["3DES_SDH_M"]

? def sr := <cap://192.168.0.21:1083;206.133.208.174:1083/08Y05bjPMtifAiO5pupFs1AOZGXS/0CFAsPlhO=U1bSRCpPyg1UrW184T>
# value: <SturdyRef>

? def evalServerPass := sr liveRef()
# value: <Eventual ref>

? def sePass1 := evalServerPass <- newScriptEvaluator(["se1", "arg"])
# value: <Eventual ref>

? 
? def r1 := evalServerPass <- execVow("2 + 3")
# value: <Eventual ref>

? r1
# value: "# valuex: 5\n\
#        \n\
#        "

? println(r1)
# valuex: 5


? def r2 := evalServerPass <- execVow(`println("Hello world")`)
# value: <Eventual ref>

? r2
# value: "# stdout: Hello world\n\
#        #         \n\
#        \n\
#        "

? println(r2)
# stdout: Hello world
#         


? def cmdLoopPass := evalServerPass <- getCmdLoop()
# value: <Eventual ref>

? def reactor {
>     match [verb, args] {
>         println(`$verb$args`)
>     }
> }
# value: <reactor>

? cmdLoopPass <- addStatusReactor(reactor)
# value: <Eventual ref>

? def r3 := evalServerPass <- execVow("3 _/ 0")
# value: <Eventual ref>

? r3
reactToEnqueue[3]
reactToSuccess[3, false]
reactToQueueEmpty[3]
# value: "# problem: <ArithmeticException: BigInteger divide by zero>\n\
#        \n\
#        "

? def r4 := evalServerPass <- execVow("interp getArgs()")
# value: <Eventual ref>

? r4
reactToEnqueue[4]
reactToSuccess[4, false]
reactToQueueEmpty[4]
# value: "# valuex: [\"bogus\", \"args\"]\n\
#        \n\
#        "

? def r5 := evalServerPass <- execVow("interp blockAtTop()")
# value: <Eventual ref>

? r5
reactToEnqueue[5]
reactToSuccess[5, true]
# value: ""

? def r6 := evalServerPass <- execVow("4 * 3")
# value: <Eventual ref>

? r6
reactToEnqueue[6]
# value: <Eventual ref>

? cmdLoopPass <- continueAtTop()
# value: <Eventual ref>

? r6
reactToSuccess[6, false]
reactToQueueEmpty[6]
# value: "# valuex: 12\n\
#        \n\
#        "

? 



1.9       +26 -12    e/src/jsrc/net/captp/jcomm/Sturdifier.java

Index: Sturdifier.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/captp/jcomm/Sturdifier.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- Sturdifier.java	2001/08/17 20:59:25	1.8
+++ Sturdifier.java	2001/08/20 05:07:43	1.9
@@ -47,18 +47,6 @@
     }
 
     /**
-     * Produce a perpetual SturdyRef for an object. <p>
-     *
-     * Just run/2 with the optExpirationDate defaulting to null.
-     *
-     * @param obj The object for which a SturdyRef is desired
-     * @return A new SturdyRef for the indicated object
-     */
-    public SturdyRef run(Object obj) {
-        return run(obj, Long.MAX_VALUE);
-    }
-    
-    /**
      * Given an obj-swissNum association, arrange for the object to last 
      * until an expiration time (so that the weak association will last till 
      * then as well) and make a SturdyRef that uses this arrangement to 
@@ -100,6 +88,18 @@
     }
     
     /**
+     * Produce a perpetual SturdyRef for an object. <p>
+     *
+     * Just run/2 with the optExpirationDate defaulting to forever.
+     *
+     * @param obj The object for which a SturdyRef is desired
+     * @return A new SturdyRef for the indicated object
+     */
+    public SturdyRef run(Object obj) {
+        return run(obj, Long.MAX_VALUE);
+    }
+    
+    /**
      * Produce a SturdyRef for an object.
      * <p>
      * The SturdyRef will designate the object across time and space, at 
@@ -119,6 +119,13 @@
     }
 
     /**
+     * optExpirationDate defaults to forever
+     */
+    public Object[] incarnate(Object obj) {
+        return incarnate(obj, Long.MAX_VALUE);
+    }
+    
+    /**
      * Produce a SturdyRef, and a swissBase so in a later incarnation of this 
      * vat a newly created object can be made to be the reincarnation of this 
      * one (from the perspective of those holding the SturdyRef). 
@@ -152,6 +159,13 @@
         SturdyRef sr = makeSturdy(obj, swissNum, optExpirationDate);
         Object[] result = { sr, swissBase };
         return result;
+    }
+    
+    /**
+     * optExpirationDate defaults to forever
+     */
+    public SturdyRef reincarnate(Object obj, BigInteger swissBase) {
+        return reincarnate(obj, swissBase, Long.MAX_VALUE);
     }
     
     /**



1.3       +24 -22    e/src/jsrc/net/vattp/data/DataPath.java

Index: DataPath.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/vattp/data/DataPath.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DataPath.java	2001/02/20 05:33:43	1.2
+++ DataPath.java	2001/08/20 05:07:43	1.3
@@ -25,7 +25,7 @@
 import java.security.KeyPair;
 import java.util.Hashtable;
 
-import org.erights.e.elib.prim.Queue;
+import org.erights.e.elib.prim.SynchQueue;
 import org.erights.e.elib.prim.Runner;
 import net.vattp.security.ESecureRandom;
 import org.erights.e.extern.timer.Clock;
@@ -53,7 +53,7 @@
  */
 /*package*/ class DataPath implements MsgHandler, TickReactor {
     
-    /** enqueued to effectively close the Queue */
+    /** enqueued to effectively close the SynchQueue */
     static /*package*/ final Object theShutDownToken = new Integer(0);
     
     /** The pong message to send when a ping message is received.  It
@@ -76,9 +76,9 @@
     /** Array of MsgHandlers indexed by message type */
     private MsgHandler[] myMsgHandlers = new MsgHandler[Msg.HIGH_MSG_TYPE+1];
     
-    /** Queue for queueing outbound messages.  This is initialized
+    /** SynchQueue for queueing outbound messages.  This is initialized
      * during construction, and set to null in shutDownPath. */
-    private Queue myWriter;
+    private SynchQueue myWriter;
     
     /** The RecvThread receiving messages for this DataConnection */
     private RecvThread myRecvThread;
@@ -212,9 +212,10 @@
 
         myConnMgr = connMgr;
         myIsIncoming = true;
-        Queue reader = commonConstructionSetup(identityKeys, 
-                                localVatID, null, //no suspendID, incoming
-                                runner, localFlattenedSearchPath, vls);
+        SynchQueue reader = 
+            commonConstructionSetup(identityKeys, 
+                                    localVatID, null, //no suspendID, incoming
+                                    runner, localFlattenedSearchPath, vls);
         
         myRemoteAddr = tcpConnection.getInetAddress().getHostAddress();
         
@@ -288,13 +289,14 @@
         } else {
             myProtocolParms = protocolParms;
         }
-        Queue reader = commonConstructionSetup(identityKeys, 
-                                               localVatID,
-                                               outgoingSuspendID,
-                                               runner,
-                                               localFlattenedSearchPath, 
-                                             //no VLS for outgoing connections
-                                               null); 
+        SynchQueue reader = 
+            commonConstructionSetup(identityKeys, 
+                                    localVatID,
+                                    outgoingSuspendID,
+                                    runner,
+                                    localFlattenedSearchPath, 
+                                    //no VLS for outgoing connections
+                                    null); 
         
         myRemoteAddr = remoteAddr;
         // Get the port number from the address
@@ -372,14 +374,14 @@
      * @param vls is the object which gives VLS look functionality, or null 
      *          if this vat doesn't support that functionality or if this
      *          is an outgoing connection.
-     * @return is the Queue object for reading the output queue.
+     * @return is the SynchQueue object for reading the output queue.
      */
-    private Queue commonConstructionSetup(KeyPair identityKeys,
-                                          String localVatID,
-                                          byte[] suspendID,
-                                          Runner runner,
-                                          String localFlattenedSearchPath,
-                                          VatLocationLookup vls)
+    private SynchQueue commonConstructionSetup(KeyPair identityKeys,
+                                               String localVatID,
+                                               byte[] suspendID,
+                                               Runner runner,
+                                               String localFlattenedSearchPath,
+                                               VatLocationLookup vls)
     {
         myIdentityKeys = identityKeys;
         myLocalVatID = localVatID;
@@ -389,7 +391,7 @@
 
         // Make a queue for outbound messages on the new connection.
         //XXX should provide a type parameter
-        Queue reader = myWriter = new Queue();
+        SynchQueue reader = myWriter = new SynchQueue();
         
         //Register to handle the PING and PONG messages.
         try {



1.3       +6 -6      e/src/jsrc/net/vattp/data/SendThread.java

Index: SendThread.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/vattp/data/SendThread.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SendThread.java	2001/04/13 08:08:33	1.2
+++ SendThread.java	2001/08/20 05:07:43	1.3
@@ -23,7 +23,7 @@
 Contributor(s): ______________________________________.
 */
 import org.erights.e.elib.prim.Runner;
-import org.erights.e.elib.prim.Queue;
+import org.erights.e.elib.prim.SynchQueue;
 import org.erights.e.develop.trace.Trace;
 import org.erights.e.develop.assertion.Assertion;
 import org.erights.e.elib.util.HexStringUtils;
@@ -90,7 +90,7 @@
     private NetAddr myLocalAddr;
     private String myRemoteAddr;
     private DataPath myDataPath;
-    private Queue myReader;
+    private SynchQueue myReader;
     private Runner myRunner;    // For synchronizing into-vat calls
     
     /** A Hashtable of the InetAddresses tried which failed due to host
@@ -134,7 +134,7 @@
      * @param remoteAddr is the IP:port address to connect to.
      * @param path is the DataPath object that receives notifications
      *              as messages are sent and error occur.
-     * @param reader is the Queue object to get messages from.
+     * @param reader is the SynchQueue object to get messages from.
      * @param runner is the Runner object to synchronize with before calling
      *              methods in the connection DataPath object
      * @param addressesTried is a Hashtable of the InetAddresses already
@@ -143,7 +143,7 @@
      *              tried again.
      */
     /*package*/ SendThread(String remoteAddr, DataPath path,
-                           Queue reader, Runner runner,
+                           SynchQueue reader, Runner runner,
                            Hashtable addressesTried) {
         super("SendThread-" + remoteAddr);
         myRemoteAddr = remoteAddr;
@@ -160,12 +160,12 @@
      * @param socket is the Socket for the new incoming connection.
      * @param path is the DataPath object that receives notifications
      *              as messages are sent and error occur.
-     * @param reader is the Queue object to get messages from.
+     * @param reader is the SynchQueue object to get messages from.
      * @param runner is the Runner object to synchronize with before calling
      *              methods in the connection DataPath object
      */
     /*package*/ SendThread(Socket socket, DataPath path,
-                           Queue reader, Runner runner) {
+                           SynchQueue reader, Runner runner) {
         super("SendThread-" + socket.getInetAddress().getHostAddress());
         mySocket = socket;
         myRemoteAddr = mySocket.getInetAddress().getHostAddress(); 



1.2       +2 -2      e/src/jsrc/net/vattp/tunnel/HTTPSocketCtl.java

Index: HTTPSocketCtl.java
===================================================================
RCS file: /cvs/e/src/jsrc/net/vattp/tunnel/HTTPSocketCtl.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- HTTPSocketCtl.java	2000/12/21 22:15:18	1.1
+++ HTTPSocketCtl.java	2001/08/20 05:07:44	1.2
@@ -27,7 +27,7 @@
 import java.net.Socket;
 
 import net.vattp.data.NetAddr;
-import org.erights.e.elib.prim.Queue;
+import org.erights.e.elib.prim.SynchQueue;
 
 /**
  * The class which controls an individual TCP socket.
@@ -50,7 +50,7 @@
     
     private boolean isNeedingSendLimitUpdate = false;
     private int myHisSendLimit = SENDLIMIT;
-    private Queue myOutputQueue = new Queue();
+    private SynchQueue myOutputQueue = new SynchQueue();
         
     /*package*/ HTTPSocketCtl(String hostPort, HTTPClient client,
                 byte connectionID) {



1.36      +1 -1      e/src/jsrc/org/erights/e/elib/prim/MirandaMethods.java

Index: MirandaMethods.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/MirandaMethods.java,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- MirandaMethods.java	2001/07/31 13:09:14	1.35
+++ MirandaMethods.java	2001/08/20 05:07:44	1.36
@@ -108,7 +108,7 @@
         }
         Class selfClass;
         if (self == null) {
-            selfClass = Object.class;
+            selfClass = Void.TYPE;
         } else {
             selfClass = self.getClass();
         }



1.6       +45 -72    e/src/jsrc/org/erights/e/elib/prim/Queue.java

Index: Queue.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/Queue.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Queue.java	2000/11/14 11:15:33	1.5
+++ Queue.java	2001/08/20 05:07:44	1.6
@@ -22,17 +22,19 @@
 import java.util.Enumeration;
 import java.util.NoSuchElementException;
 
-
 /**
- * A conventional fifo queue in which dequeued items are removed in the 
- * same order they were enqueued.  An untyped queue can hold any object 
- * (except null).  A queue can be created with a dynamic type, in which case,
- * at no extra overhead, enqueue will only enqueue objects of that type (or a
- * subtype, but not null).  This check imposes no *extra* overhead, since 
- * java always makes us pay for a dynamic type check on array store anyway.
- *
- * Unlike earlier, Queue is now a thread-safe data structure,
- * providing its own lock, and a blocking dequeue() operation.
+ * A conventional fifo queue in which dequeued items are removed in
+ * the same order they were enqueued.
+ * <p>
+ * An untyped queue can hold any object (except null).  A queue can be
+ * created with a dynamic type, in which case, at no extra overhead,
+ * enqueue will only enqueue objects of that type (or a subtype, but
+ * not null).  This check imposes no *extra* overhead, since java
+ * always makes us pay for a dynamic type check on array store anyway.
+ * <p>
+ * The class Queue itself is no longer thread safe, instead being
+ * optimized for using inside one vat.  See the subclass {@link
+ * SynchQueue} for a thread-safe variant with a blocking operation.
  *
  * @see org.erights.e.elib.prim.Runner
  * @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
@@ -41,7 +43,6 @@
     
     static private final int INITIAL_SIZE = 400;
 
-    private Object myQLock;
     private Object[] myStuff;
     private int myMaxSize;
     private int myCurSize;
@@ -61,7 +62,6 @@
      * @param elementType may not be a primitive (ie, scalar) type.
      */
     public Queue(Class elementType) {
-        myQLock = new Object();
         if (elementType.isPrimitive()) {
             throw new IllegalArgumentException("must be reference type: " + 
                                                elementType);
@@ -74,28 +74,6 @@
     }
 
     /**
-     * Get the least-recently-added element off of the queue.  If the queue 
-     * is currently empty, block until there is an element that can be
-     * dequeued. 
-     */
-    public Object dequeue() {
-        synchronized(myQLock) {
-            while(true) {
-                Object result = optDequeue();
-                if (result != null) {
-                    return result;
-                }
-                try {
-                    myQLock.wait();
-                } catch (InterruptedException ie) {
-                    //ignored on purpose, but we do recheck the queue rather 
-                    //than just waiting again
-                }
-            }
-        }
-    }
-
-    /**
      * Add a new element to the queue.
      *
      * @param newElement the object to be added to the end of the queue.
@@ -107,36 +85,33 @@
         if (newElement == null) {
             throw new NullPointerException("cannot enqueue a null");
         }
-        synchronized(myQLock) {
-            // grow array if necessary
-            if (myCurSize == myMaxSize) {
-                int newSize = (myMaxSize * 3) / 2 + 10;
-                Class elementType = myStuff.getClass().getComponentType();
-                Object[] stuff = (Object[])Array.newInstance(elementType,
-                                                             newSize);
-
-                // note: careful code to avoid inadvertantly
-                // reordrering messages 
-                System.arraycopy(myStuff, myOut, stuff, 0, myMaxSize - myOut);
-                if (myOut != 0) {
-                    System.arraycopy(myStuff, 0, stuff, myMaxSize - myOut, 
-                                     myOut);
-                }
-                myOut = 0;
-                myIn = myMaxSize;
-                myStuff = stuff;
-                myMaxSize = newSize;
-            }
-            //will throw ArrayStoreException if newElement's type doesn't 
-            //conform to elementType
-            myStuff[myIn] = newElement;
-            myIn++;
-            if (myIn == myMaxSize) {
-                myIn = 0;
+        // grow array if necessary
+        if (myCurSize == myMaxSize) {
+            int newSize = (myMaxSize * 3) / 2 + 10;
+            Class elementType = myStuff.getClass().getComponentType();
+            Object[] stuff = (Object[])Array.newInstance(elementType,
+                                                         newSize);
+            
+            // note: careful code to avoid inadvertantly
+            // reordrering messages 
+            System.arraycopy(myStuff, myOut, stuff, 0, myMaxSize - myOut);
+            if (myOut != 0) {
+                System.arraycopy(myStuff, 0, stuff, myMaxSize - myOut, 
+                                 myOut);
             }
-            myCurSize++;
-            myQLock.notifyAll();
+            myOut = 0;
+            myIn = myMaxSize;
+            myStuff = stuff;
+            myMaxSize = newSize;
+        }
+        //will throw ArrayStoreException if newElement's type doesn't 
+        //conform to elementType
+        myStuff[myIn] = newElement;
+        myIn++;
+        if (myIn == myMaxSize) {
+            myIn = 0;
         }
+        myCurSize++;
     }
 
     /**
@@ -175,17 +150,15 @@
             return null;
         }
 
-        synchronized(myQLock) {
-            Object result = myStuff[myOut];
+        Object result = myStuff[myOut];
 
-            myStuff[myOut] = null;
-            myOut++;
-            if (myOut == myMaxSize) {
-                myOut = 0;
-            }
-            myCurSize--;
-
-            return result;
+        myStuff[myOut] = null;
+        myOut++;
+        if (myOut == myMaxSize) {
+            myOut = 0;
         }
+        myCurSize--;
+        
+        return result;
     }
 }



1.24      +4 -4      e/src/jsrc/org/erights/e/elib/prim/Runner.java

Index: Runner.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/Runner.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- Runner.java	2001/07/08 02:13:05	1.23
+++ Runner.java	2001/08/20 05:07:44	1.24
@@ -42,9 +42,9 @@
     static private int DEQUEUE_GRANULARITY = 25;
 
     /**
-     * Note that Queue is a thread-safe data structure with its own lock.
+     * Note that SynchQueue is a thread-safe data structure with its own lock.
      */
-    private Queue myQ;
+    private SynchQueue myQ;
 
     /**
      * If we ever go orthogonal again, myThread must not be
@@ -91,7 +91,7 @@
      * @param name is the name to give to the thread created.
      */
     public Runner(String name) {
-        myQ = new Queue(Runnable.class);
+        myQ = new SynchQueue(Runnable.class);
         myThread = new RunnerThread(this, name);
         myWeakPtrQueue = new ReferenceQueue();
         Thread wpt = new WeakPtrThread(myWeakPtrQueue,
@@ -160,7 +160,7 @@
     }
 
     /**
-     * Queue's something for this Runnable's thread to do.  May be called
+     * Enqueue's something for this Runnable's thread to do.  May be called
      * from any thead.
      */
     public void enqueue(Runnable todo) {



1.14      +1 -0      e/src/jsrc/org/erights/e/elib/prim/StaticMaker.java

Index: StaticMaker.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/prim/StaticMaker.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- StaticMaker.java	2001/08/19 06:35:55	1.13
+++ StaticMaker.java	2001/08/20 05:07:44	1.14
@@ -83,6 +83,7 @@
         "org.erights.e.elib.quasi.Substituter",
         "org.erights.e.elib.ref.Ref",
         "org.erights.e.elib.prim.E",
+        "org.erights.e.elib.prim.Queue",
         "org.erights.e.elib.prim.Thrower",
         "org.erights.e.elib.sealing.Brand",
         "org.erights.e.elib.slot.NullOkMaker",



1.20      +1 -0      e/src/jsrc/org/erights/e/elib/tables/ConstMap.java

Index: ConstMap.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/ConstMap.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- ConstMap.java	2001/08/18 05:19:38	1.19
+++ ConstMap.java	2001/08/20 05:07:44	1.20
@@ -27,6 +27,7 @@
 import org.erights.e.elib.base.TextWriter;
 import org.erights.e.elib.prim.StaticMaker;
 import org.erights.e.elib.serial.PassByConstruction;
+import org.erights.e.elib.serial.Persistent;
 import org.erights.e.elib.serial.RemoteDelivery;
 import org.erights.e.elib.tables.Selfless;
 import org.erights.e.elib.util.ArityMismatchException;



1.13      +1 -1      e/src/jsrc/org/erights/e/extern/timer/TimerThread.java

Index: TimerThread.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/extern/timer/TimerThread.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- TimerThread.java	2001/07/31 13:09:14	1.12
+++ TimerThread.java	2001/08/20 05:07:44	1.13
@@ -26,7 +26,7 @@
  */
 /*package*/ class TimerThread extends Thread
 {
-    /** Queue of pending timer events */
+    /** queue of pending timer events */
     private TimerQEntry myTopEntry = null;
 
     /** Flag to control execution */



1.20      +40 -1     e/src/jsrc/org/erights/e/meta/java/io/FileSugar.java

Index: FileSugar.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/meta/java/io/FileSugar.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- FileSugar.java	2001/08/13 01:47:03	1.19
+++ FileSugar.java	2001/08/20 05:07:44	1.20
@@ -24,8 +24,11 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.math.BigInteger;
 import java.security.NoSuchAlgorithmException;
 import org.erights.e.elib.base.TextWriter;
@@ -213,11 +216,45 @@
     throws NoSuchAlgorithmException, FileNotFoundException, IOException {
         return InputStreamSugar.getCryptoHash(new FileInputStream(self));
     }
+    
+    /**
+     * Returns the binary contents of the file as an array of bytes.
+     */
+    static public byte[] getBytes(File self) throws IOException {
+        InputStream inp = new FileInputStream(self);
+        byte[] result;
+        try {
+            result = InputStreamSugar.readAvailable(inp);
+        } finally {
+            inp.close();
+        }
+        if (result == null || result.length != self.length()) {
+            throw new IOException("reading " + self.getPath());
+        }
+        return result;
+    }
+    
+    /**
+     * Sets the binary contents of the file to 'contents'.
+     * <p>
+     * Should be made crash-safe
+     */
+    static public void setBytes(File self, byte[] contents)
+    throws IOException {
+        OutputStream out = new FileOutputStream(self);
+        try {
+            out.write(contents);
+        } finally {
+            out.close();
+        }
+    }
 
     /** 
      * Write the file so that its contents represents the string
      * 'text', turning '\n's into platform newlines, and converting to
-     * UTF-8 
+     * UTF-8.
+     * <p>
+     * Should be made crash-safe
      */
     static public void setText(File self, String text) throws IOException {
         writeText(self, text, false);
@@ -248,6 +285,8 @@
      * Write the file (or append to the file) so that its contents
      * represents the string 'text', turning '\n's into platform
      * newlines, and converting to UTF-8
+     * <p>
+     * Should be made crash-safe
      */
     static private void writeText(File self, String text, boolean append)
          throws IOException



1.10      +18 -0     e/src/jsrc/org/erights/e/meta/java/io/InputStreamSugar.java

Index: InputStreamSugar.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/meta/java/io/InputStreamSugar.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- InputStreamSugar.java	2001/08/13 01:47:03	1.9
+++ InputStreamSugar.java	2001/08/20 05:07:44	1.10
@@ -60,6 +60,24 @@
         return new BigInteger(1, sha.digest());
     }
 
+    /**
+     * Reads the currently available bytes (presumably without blocking, 
+     * since they are said to be available).
+     */
+    static public byte[] readAvailable(InputStream self) throws IOException {
+        int size = self.available();
+        byte[] result = new byte[size];
+        if (0 == size) {
+            return result;
+        }
+        int len = self.read(result);
+        if (len == size) {
+            return result;
+        }
+        byte[] section = new byte[len];
+        System.arraycopy(result, 0, section, 0, len);
+        return section;
+    }
 
     /**
      * A InputStream prints as &lt;InputStream&gt;