summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorstepancheg <stepancheg@epfl.ch>2008-06-10 19:52:33 +0000
committerstepancheg <stepancheg@epfl.ch>2008-06-10 19:52:33 +0000
commit740c36ace1b1efd328bc887a935b4e1ce2a6f1ef (patch)
tree52d0a06160dca8ab06f4a87997163f93f0f216e3 /src
parent86d6fb22d0460739428fdc25085761180aa10fc2 (diff)
downloadscala-740c36ace1b1efd328bc887a935b4e1ce2a6f1ef.tar.gz
scala-740c36ace1b1efd328bc887a935b4e1ce2a6f1ef.tar.bz2
scala-740c36ace1b1efd328bc887a935b4e1ce2a6f1ef.zip
SyncVar enhancements:
* deprecation of "exception" field * addition of blocking-queue-like "take", "put" methods * change of "unset" signature
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/concurrent/SyncVar.scala19
-rw-r--r--src/library/scala/concurrent/ops.scala29
2 files changed, 41 insertions, 7 deletions
diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala
index 6b9ca33395..c04268990a 100644
--- a/src/library/scala/concurrent/SyncVar.scala
+++ b/src/library/scala/concurrent/SyncVar.scala
@@ -28,6 +28,14 @@ class SyncVar[A] {
else throw exception.get
}
+ def take() = synchronized {
+ try {
+ get
+ } finally {
+ unset()
+ }
+ }
+
def set(x: A) = synchronized {
value = x
isDefined = true
@@ -41,6 +49,9 @@ class SyncVar[A] {
notifyAll()
}
+ /**
+ * @deprecated Will be removed in 2.8. SyncVar should not allow exception by design.
+ */
def setWithCatch(x: => A) = synchronized {
try {
this set x
@@ -51,12 +62,18 @@ class SyncVar[A] {
}
}
+ def put(x: A) = synchronized {
+ while (isDefined) wait()
+ set(x)
+ }
+
def isSet: Boolean = synchronized {
isDefined
}
- def unset = synchronized {
+ def unset(): Unit = synchronized {
isDefined = false
+ notifyAll()
}
}
diff --git a/src/library/scala/concurrent/ops.scala b/src/library/scala/concurrent/ops.scala
index 0d3c485300..3bb0fb9857 100644
--- a/src/library/scala/concurrent/ops.scala
+++ b/src/library/scala/concurrent/ops.scala
@@ -20,6 +20,17 @@ import java.lang.Thread
* @version 1.0, 12/03/2003
*/
object ops {
+ /**
+ * If expression computed successfully return it in <code>Left</code>,
+ * otherwise return exception in <code>Right</code>.
+ */
+ private def tryCatch[A](left: => A): Either[A, Throwable] = {
+ try {
+ Left(left)
+ } catch {
+ case t => Right(t)
+ }
+ }
/**
* @param p ...
@@ -34,9 +45,12 @@ object ops {
* @return ...
*/
def future[A](p: => A): () => A = {
- val result = new SyncVar[A]
- spawn { result setWithCatch p }
- () => result.get
+ val result = new SyncVar[Either[A, Throwable]]
+ spawn { result set tryCatch(p) }
+ () => result.get match {
+ case Left(a) => a
+ case Right(t) => throw t
+ }
}
/**
@@ -45,9 +59,12 @@ object ops {
* @return ...
*/
def par[A, B](xp: => A, yp: => B): (A, B) = {
- val y = new SyncVar[B]
- spawn { y setWithCatch yp }
- (xp, y.get)
+ val y = new SyncVar[Either[B, Throwable]]
+ spawn { y set tryCatch(yp) }
+ (xp, y.get match {
+ case Left(b) => b
+ case Right(t) => throw t
+ })
}
/**