diff options
author | Philipp Haller <hallerp@gmail.com> | 2010-04-28 15:26:22 +0000 |
---|---|---|
committer | Philipp Haller <hallerp@gmail.com> | 2010-04-28 15:26:22 +0000 |
commit | 231cfbe1c023ccf9e1bc437e5098f41b121fffa8 (patch) | |
tree | 815855c96eeac800a3957db4ec97c3c2539cef4a | |
parent | 32cff2050f93bc6012b4354c0156b4f8e40f1719 (diff) | |
download | scala-231cfbe1c023ccf9e1bc437e5098f41b121fffa8.tar.gz scala-231cfbe1c023ccf9e1bc437e5098f41b121fffa8.tar.bz2 scala-231cfbe1c023ccf9e1bc437e5098f41b121fffa8.zip |
Closes #3365.
-rw-r--r-- | src/actors/scala/actors/AbstractActor.scala | 2 | ||||
-rw-r--r-- | src/actors/scala/actors/ActorCanReply.scala | 2 | ||||
-rw-r--r-- | src/actors/scala/actors/CanReply.scala | 8 | ||||
-rw-r--r-- | src/actors/scala/actors/Channel.scala | 22 | ||||
-rw-r--r-- | src/actors/scala/actors/ReactorCanReply.scala | 6 | ||||
-rw-r--r-- | src/actors/scala/actors/remote/Proxy.scala | 6 | ||||
-rw-r--r-- | test/files/jvm/t3365.check | 5 | ||||
-rw-r--r-- | test/files/jvm/t3365.scala | 65 |
8 files changed, 105 insertions, 11 deletions
diff --git a/src/actors/scala/actors/AbstractActor.scala b/src/actors/scala/actors/AbstractActor.scala index 80b1e76b30..f97a1c3e2a 100644 --- a/src/actors/scala/actors/AbstractActor.scala +++ b/src/actors/scala/actors/AbstractActor.scala @@ -19,6 +19,8 @@ package scala.actors */ trait AbstractActor extends OutputChannel[Any] with CanReply[Any, Any] { + type Future[+R] = scala.actors.Future[R] + private[actors] def exiting: Boolean = false private[actors] def linkTo(to: AbstractActor): Unit diff --git a/src/actors/scala/actors/ActorCanReply.scala b/src/actors/scala/actors/ActorCanReply.scala index 7b8ac27405..a6a81815c1 100644 --- a/src/actors/scala/actors/ActorCanReply.scala +++ b/src/actors/scala/actors/ActorCanReply.scala @@ -50,7 +50,7 @@ private[actors] trait ActorCanReply extends ReactorCanReply { } override def !!(msg: Any): Future[Any] = { - val noTransform: PartialFunction[Any, Any] = { case x => x} + val noTransform: PartialFunction[Any, Any] = { case x => x } this !! (msg, noTransform) } diff --git a/src/actors/scala/actors/CanReply.scala b/src/actors/scala/actors/CanReply.scala index 99e1169900..034eea8479 100644 --- a/src/actors/scala/actors/CanReply.scala +++ b/src/actors/scala/actors/CanReply.scala @@ -19,6 +19,8 @@ package scala.actors */ trait CanReply[-T, +R] { + type Future[+P] <: () => P + /** * Sends <code>msg</code> to this $actor and * awaits reply (synchronous). @@ -47,8 +49,7 @@ trait CanReply[-T, +R] { * @param msg the message to be sent * @return the future */ - def !!(msg: T): () => R = - () => this !? msg + def !!(msg: T): Future[R] /** * Sends <code>msg</code> to this $actor and @@ -61,7 +62,6 @@ trait CanReply[-T, +R] { * @param handler the function to be applied to the response * @return the future */ - def !![P](msg: T, handler: PartialFunction[R, P]): () => P = - () => handler(this !? msg) + def !![P](msg: T, handler: PartialFunction[R, P]): Future[P] } diff --git a/src/actors/scala/actors/Channel.scala b/src/actors/scala/actors/Channel.scala index b3772c6109..bf5d9261db 100644 --- a/src/actors/scala/actors/Channel.scala +++ b/src/actors/scala/actors/Channel.scala @@ -40,6 +40,8 @@ case class ! [a](ch: Channel[a], msg: a) */ class Channel[Msg](val receiver: Actor) extends InputChannel[Msg] with OutputChannel[Msg] with CanReply[Msg, Any] { + type Future[+P] = scala.actors.Future[P] + def this() = this(Actor.self) def !(msg: Msg) { @@ -108,4 +110,24 @@ class Channel[Msg](val receiver: Actor) extends InputChannel[Msg] with OutputCha } } + def !![A](msg: Msg, handler: PartialFunction[Any, A]): Future[A] = { + val ftch = new Channel[A](Actor.self(receiver.scheduler)) + receiver.send(scala.actors.!(this, msg), new OutputChannel[Any] { + def !(msg: Any) = + ftch ! handler(msg) + def send(msg: Any, replyTo: OutputChannel[Any]) = + ftch.send(handler(msg), replyTo) + def forward(msg: Any) = + ftch.forward(handler(msg)) + def receiver = + ftch.receiver + }) + Futures.fromInputChannel(ftch) + } + + def !!(msg: Msg): Future[Any] = { + val noTransform: PartialFunction[Any, Any] = { case x => x } + this !! (msg, noTransform) + } + } diff --git a/src/actors/scala/actors/ReactorCanReply.scala b/src/actors/scala/actors/ReactorCanReply.scala index 9002a55b87..e279845c9b 100644 --- a/src/actors/scala/actors/ReactorCanReply.scala +++ b/src/actors/scala/actors/ReactorCanReply.scala @@ -19,6 +19,8 @@ package scala.actors private[actors] trait ReactorCanReply extends CanReply[Any, Any] { _: ReplyReactor => + override type Future[+P] = scala.actors.Future[P] + def !?(msg: Any): Any = (this !! msg)() @@ -39,10 +41,10 @@ private[actors] trait ReactorCanReply extends CanReply[Any, Any] { res.get(msec) } - override def !!(msg: Any): Future[Any] = + def !!(msg: Any): Future[Any] = this !! (msg, { case x => x }) - override def !![A](msg: Any, handler: PartialFunction[Any, A]): Future[A] = { + def !![A](msg: Any, handler: PartialFunction[Any, A]): Future[A] = { val myself = Actor.rawSelf(this.scheduler) val ftch = new ReactChannel[A](myself) val res = new scala.concurrent.SyncVar[A] diff --git a/src/actors/scala/actors/remote/Proxy.scala b/src/actors/scala/actors/remote/Proxy.scala index f9a6cd8fed..ac5951ed85 100644 --- a/src/actors/scala/actors/remote/Proxy.scala +++ b/src/actors/scala/actors/remote/Proxy.scala @@ -20,8 +20,6 @@ import scala.collection.mutable.HashMap private[remote] class Proxy(node: Node, name: Symbol, @transient var kernel: NetKernel) extends AbstractActor { import java.io.{IOException, ObjectOutputStream, ObjectInputStream} - type Future[+R] = scala.actors.Future[R] - @transient private[remote] var del: Actor = null startDelegate() @@ -66,10 +64,10 @@ private[remote] class Proxy(node: Node, name: Symbol, @transient var kernel: Net def !?(msec: Long, msg: Any): Option[Any] = del !? (msec, msg) - override def !!(msg: Any): Future[Any] = + def !!(msg: Any): Future[Any] = del !! msg - override def !![A](msg: Any, f: PartialFunction[Any, A]): Future[A] = + def !![A](msg: Any, f: PartialFunction[Any, A]): Future[A] = del !! (msg, f) def linkTo(to: AbstractActor): Unit = diff --git a/test/files/jvm/t3365.check b/test/files/jvm/t3365.check new file mode 100644 index 0000000000..0944b17279 --- /dev/null +++ b/test/files/jvm/t3365.check @@ -0,0 +1,5 @@ +'hello +'hello +'hello +'hello +'hello diff --git a/test/files/jvm/t3365.scala b/test/files/jvm/t3365.scala new file mode 100644 index 0000000000..b94e804e63 --- /dev/null +++ b/test/files/jvm/t3365.scala @@ -0,0 +1,65 @@ +import scala.actors.{ReplyReactor, Channel, Actor, Future} + +case class ChannelMsg(chan: Channel[Any]) + +class MyActor extends Actor { + def act() { + try { + val chan = new Channel[Any](this) + loop { + react { + case other: ReplyReactor => + other ! ChannelMsg(chan) + loop { + chan.react { + case 'hello => + reply('hello) + case 'stop => + exit() + } + } + } + } + } catch { + case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] => + e.printStackTrace() + } + } +} + +object Test { + def main(args: Array[String]) { + val a = new MyActor + a.start() + + val b = new Actor { + def act() { + try { + react { + case ChannelMsg(c) => + var i = 0 + loop { + i += 1 + val ft: Future[Any] = c !! 'hello + ft.inputChannel.react { + case msg => + if (i % 10000 == 0) + println(msg) + if (i >= 50000) { + c ! 'stop + exit() + } + } + } + } + } catch { + case e: Throwable if !e.isInstanceOf[scala.util.control.ControlThrowable] => + e.printStackTrace() + } + } + } + b.start() + + a ! b + } +} |