summaryrefslogtreecommitdiff
path: root/test/files/pos/MailBox.scala
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2005-12-16 18:29:42 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2005-12-16 18:29:42 +0000
commitdf50e05006b43b007c2587549030d24b5c154398 (patch)
tree9edfb1fb5b8c04350a00c163cfcdb1fccd79e3aa /test/files/pos/MailBox.scala
parent17e2b1c2a6f69ba74e79c30d1e44195fe732e3e3 (diff)
downloadscala-df50e05006b43b007c2587549030d24b5c154398.tar.gz
scala-df50e05006b43b007c2587549030d24b5c154398.tar.bz2
scala-df50e05006b43b007c2587549030d24b5c154398.zip
'test-nsc' has been moved to 'test'.
Diffstat (limited to 'test/files/pos/MailBox.scala')
-rw-r--r--test/files/pos/MailBox.scala83
1 files changed, 83 insertions, 0 deletions
diff --git a/test/files/pos/MailBox.scala b/test/files/pos/MailBox.scala
new file mode 100644
index 0000000000..b1ea818f60
--- /dev/null
+++ b/test/files/pos/MailBox.scala
@@ -0,0 +1,83 @@
+package test;
+
+import scala.concurrent._;
+
+class MailBox {
+ private class LinkedList[a] {
+ var elem: a = _;
+ var next: LinkedList[a] = null;
+ }
+
+ private def insert[a](l: LinkedList[a], x: a): LinkedList[a] = {
+ l.next = new LinkedList[a];
+ l.next.elem = x;
+ l.next.next = l.next;
+ l
+ }
+
+ private abstract class Receiver {
+ def isDefined(msg: Any): boolean;
+ var msg: Any = null;
+ }
+
+ private val sent = new LinkedList[Any];
+ private var lastSent = sent;
+ private val receivers = new LinkedList[Receiver];
+ private var lastReceiver = receivers;
+
+ def send(msg: Any): unit = synchronized {
+ var r = receivers;
+ var r1 = r.next;
+ while (r1 != null && !r1.elem.isDefined(msg)) {
+ r = r1; r1 = r1.next;
+ }
+ if (r1 != null) {
+ r.next = r1.next; r1.elem.msg = msg; r1.elem.notify();
+ } else {
+ lastSent = insert(lastSent, msg);
+ }
+ }
+
+ def receive[a](f: PartialFunction[Any, a]): a = {
+ val msg: Any = synchronized {
+ var s = sent;
+ var s1 = s.next;
+ while (s1 != null && !f.isDefinedAt(s1.elem)) {
+ s = s1; s1 = s1.next
+ }
+ if (s1 != null) {
+ s.next = s1.next; s1.elem
+ } else {
+ val r = insert(lastReceiver, new Receiver {
+ def isDefined(msg: Any) = f.isDefinedAt(msg);
+ });
+ lastReceiver = r;
+ r.elem.wait();
+ r.elem.msg
+ }
+ }
+ f(msg)
+ }
+
+ def receiveWithin[a](msec: long)(f: PartialFunction[Any, a]): a = {
+ val msg: Any = synchronized {
+ var s = sent;
+ var s1 = s.next;
+ while (s1 != null && !f.isDefinedAt(s1.elem)) {
+ s = s1; s1 = s1.next ;
+ }
+ if (s1 != null) {
+ s.next = s1.next; s1.elem
+ } else {
+ val r = insert(lastReceiver, new Receiver {
+ def isDefined(msg: Any) = f.isDefinedAt(msg);
+ });
+ lastReceiver = r;
+ r.elem.wait(msec);
+ if (r.elem.msg == null) r.elem.msg = TIMEOUT;
+ r.elem.msg
+ }
+ }
+ f(msg)
+ }
+}