1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
Condition {
var <>test, waitingThreads;
*new { arg test=false;
^super.newCopyArgs(test, Array(8))
}
wait {
if (test.value.not, {
waitingThreads = waitingThreads.add(thisThread.threadPlayer);
\hang.yield;
});
}
hang { arg value = \hang;
// ignore the test, just wait
waitingThreads = waitingThreads.add(thisThread.threadPlayer);
value.yield;
}
signal {
var tempWaitingThreads, time;
if (test.value, {
time = thisThread.seconds;
tempWaitingThreads = waitingThreads;
waitingThreads = nil;
tempWaitingThreads.do({ arg thread;
thread.clock.sched(0, thread);
});
});
}
unhang {
var tempWaitingThreads, time;
// ignore the test, just resume all waiting threads
time = thisThread.seconds;
tempWaitingThreads = waitingThreads;
waitingThreads = nil;
tempWaitingThreads.do({ arg thread;
thread.clock.sched(0, thread);
});
}
}
FlowVar {
var value = \unbound;
var condition;
*new { arg inVal = \unbound;
^super.new.init(inVal)
}
init { arg inVal;
value = inVal;
condition = Condition { value != \unbound };
}
value_ { arg inVal;
if (value != \unbound) {
Error("cannot rebind a FlowVar").throw
};
value = inVal;
condition.signal;
}
value {
condition.wait
^value
}
}
|