[e-cvs] cvs commit: e/src/esrc/org/erights/e/elang/cmd controlLoopMakerAuthor.emaker controlLoopMakerAuthor.updoc
markm@eros.cs.jhu.edu
markm@eros.cs.jhu.edu
Wed, 15 Aug 2001 23:05:38 -0400
markm 01/08/15 23:05:37
Added: src/esrc/org/erights/e/elang/cmd
controlLoopMakerAuthor.emaker
controlLoopMakerAuthor.updoc
Log:
beginnings of command loop in E
Revision Changes Path
1.1 e/src/esrc/org/erights/e/elang/cmd/controlLoopMakerAuthor.emaker
Index: controlLoopMakerAuthor.emaker
===================================================================
def controlLoopMakerAuthor(QueueMaker) :any {
class controlLoopMaker() :any {
var myShouldBlock := false
var myIsAlarmSet := false
# if non-null, we *should* exit
var myOptExitPair := null
# if non-null, we *have* exitted
var myOptQueue := QueueMaker new()
def internalLoop
def setAlarm() {
if (! myIsAlarmSet && ! myShouldBlock && myOptQueue != null) {
myIsAlarmSet := true
internalLoop <- ()
}
}
def bind internalLoop() {
myIsAlarmSet := false
if (myShouldBlock) {
# do nothing
} else if (myOptExitPair != null) {
myOptQueue := null
} else if (myOptQueue optDequeue() =~ runnable ? (runnable != null)) {
try {
runnable()
} catch problem {
myOptExitPair := [-1, problem]
}
setAlarm()
} else {
# queue is empty, do nothing
}
}
def controlLoop {
to blockAtTop() {
myShouldBlock := true
}
to continueAtTop() {
myShouldBlock := false
setAlarm()
}
to waitAtTop(ref) {
Ref whenResolved(ref, def _(_){
controlLoop continueAtTop()
})
}
to exitAtTop() {
myOptExitPair := [0, null]
setAlarm()
}
to exitAtTop(exitCode, optProblem) {
myOptExitPair := [exitCode, optProblem]
setAlarm()
}
to enqueue(runnable) {
if (myOptQueue != null) {
myOptQueue enqueue(runnable)
setAlarm()
}
}
# 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 getOptExitPair() :any {
if (myOptQueue == null) {
require(myOptExitPair != null,
thunk{"internal: no exit pair"})
myOptExitPair
} else {
null
}
}
}
}
}
1.1 e/src/esrc/org/erights/e/elang/cmd/controlLoopMakerAuthor.updoc
Index: controlLoopMakerAuthor.updoc
===================================================================
? def QueueMaker := <unsafe:org.erights.e.elib.prim.Queue>
# value: <unsafe:org.erights.e.elib.prim.Queue>
? def controlLoopMaker := <import:org.erights.e.elang.cmd.controlLoopMakerAuthor>(QueueMaker)
# value: <controlLoopMaker>
? def ctrl := controlLoopMaker new()
# value: <controlLoop>
? ctrl enqueue(thunk{println("foo")})
?
foo
? (ctrl enqueue(thunk{println("bar")})
> ctrl blockAtTop()
> ctrl enqueue(thunk{println("baz")})
> )
?
? ctrl continueAtTop()
?
bar
baz
? def [p,r] := PromiseMaker()
# value: [<Eventual ref>, <Open Resolver>]
? def event() {
> println("before")
> ctrl blockAtTop()
> println("after")
> ctrl enqueue(thunk{println("next")})
> ctrl waitAtTop(p)
> }
# value: <event>
? ctrl enqueue(event)
?
before
after
?
? r resolve(3)
?
next
? ctrl getOptExitPair()
? def event2() {
> ctrl exitAtTop()
> println(`exit: ${ctrl getOptExitPair()}`)
> ctrl enqueue(thunk{println("already dead")})
> }
# value: <event2>
? ctrl enqueue(event2)
?
exit: null
?
? ctrl getOptExitPair()
# value: [0, null]
?