[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 <InputStream>