From 0b98fa17637ef4c7cf8929467908aff43b6e9cd3 Mon Sep 17 00:00:00 2001 From: michelou Date: Wed, 11 Jul 2007 14:52:34 +0000 Subject: [PATCH] added Stepan's patch ops/SyncVar git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@12271 5e8d7ff9-d8ef-0310-90f0-a4852d11357a --- docs/examples/actors/channels.scala | 6 ++-- src/library/scala/concurrent/SyncVar.scala | 33 +++++++++++++++++----- src/library/scala/concurrent/ops.scala | 20 ++++++------- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/docs/examples/actors/channels.scala b/docs/examples/actors/channels.scala index 40ddeecbc..3c0dbf232 100644 --- a/docs/examples/actors/channels.scala +++ b/docs/examples/actors/channels.scala @@ -4,15 +4,15 @@ import scala.actors._ import scala.actors.Actor._ object channels extends Application { - case class Msg(ch1: Channel[int], ch2: Channel[String]) + case class Msg(ch1: Channel[Int], ch2: Channel[String]) val a = actor { - val Ch1 = new Channel[int] + val Ch1 = new Channel[Int] val Ch2 = new Channel[String] b ! Msg(Ch1, Ch2) - val ICh1 = Ch1.asInstanceOf[InputChannel[int]] + val ICh1 = Ch1.asInstanceOf[InputChannel[Int]] val ICh2 = Ch2.asInstanceOf[InputChannel[String]] react { diff --git a/src/library/scala/concurrent/SyncVar.scala b/src/library/scala/concurrent/SyncVar.scala index 9b852e4cb..413dc5dca 100644 --- a/src/library/scala/concurrent/SyncVar.scala +++ b/src/library/scala/concurrent/SyncVar.scala @@ -1,7 +1,7 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ @@ -14,24 +14,43 @@ package scala.concurrent /** The class SyncVar ... * - * @author Martin Odersky + * @author Martin Odersky, Stepan Koltsov * @version 1.0, 10/03/2003 */ -class SyncVar[a] { +class SyncVar[A] { private var isDefined: Boolean = false - private var value: a = _ + private var value: A = _ + private var exception: Option[Throwable] = None def get = synchronized { while (!isDefined) wait() - value + if (exception.isEmpty) value + else throw exception.get } - def set(x: a) = synchronized { + def set(x: A) = synchronized { value = x isDefined = true + exception = None notifyAll() } + private def setException(e: Throwable) = synchronized { + exception = Some(e) + isDefined = true + notifyAll() + } + + def setWithCatch(x: => A) = synchronized { + try { + this set x + } catch { + case e => + this setException e + throw e + } + } + def isSet: Boolean = synchronized { isDefined } diff --git a/src/library/scala/concurrent/ops.scala b/src/library/scala/concurrent/ops.scala index 365a4c895..b62f0df50 100644 --- a/src/library/scala/concurrent/ops.scala +++ b/src/library/scala/concurrent/ops.scala @@ -1,7 +1,7 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ @@ -16,7 +16,7 @@ import java.lang.Thread /** The object ops ... * - * @author Martin Odersky + * @author Martin Odersky, Stepan Koltsov * @version 1.0, 12/03/2003 */ object ops { @@ -33,9 +33,9 @@ object ops { * @param p ... * @return ... */ - def future[a](p: => a): () => a = { - val result = new SyncVar[a] - spawn { result set p } + def future[A](p: => A): () => A = { + val result = new SyncVar[A] + spawn { result setWithCatch p } () => result.get } @@ -44,9 +44,9 @@ object ops { * @param yp ... * @return ... */ - def par[a, b](xp: => a, yp: => b): (a, b) = { - val y = new SyncVar[b] - spawn { y set yp } + def par[A, B](xp: => A, yp: => B): (A, B) = { + val y = new SyncVar[B] + spawn { y setWithCatch yp } (xp, y.get) } @@ -55,7 +55,7 @@ object ops { * @param end ... * @param p ... */ - def replicate(start: Int, end: Int)(p: Int => Unit): Unit = { + def replicate(start: Int, end: Int)(p: Int => Unit) { if (start == end) () else if (start + 1 == end)