diff options
author | stepancheg <stepancheg@epfl.ch> | 2008-06-10 19:52:33 +0000 |
---|---|---|
committer | stepancheg <stepancheg@epfl.ch> | 2008-06-10 19:52:33 +0000 |
commit | 740c36ace1b1efd328bc887a935b4e1ce2a6f1ef (patch) | |
tree | 52d0a06160dca8ab06f4a87997163f93f0f216e3 /src/library | |
parent | 86d6fb22d0460739428fdc25085761180aa10fc2 (diff) | |
download | scala-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/library')
-rw-r--r-- | src/library/scala/concurrent/SyncVar.scala | 19 | ||||
-rw-r--r-- | src/library/scala/concurrent/ops.scala | 29 |
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 + }) } /** |