summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Haller <hallerp@gmail.com>2010-04-28 15:26:22 +0000
committerPhilipp Haller <hallerp@gmail.com>2010-04-28 15:26:22 +0000
commit231cfbe1c023ccf9e1bc437e5098f41b121fffa8 (patch)
tree815855c96eeac800a3957db4ec97c3c2539cef4a
parent32cff2050f93bc6012b4354c0156b4f8e40f1719 (diff)
downloadscala-231cfbe1c023ccf9e1bc437e5098f41b121fffa8.tar.gz
scala-231cfbe1c023ccf9e1bc437e5098f41b121fffa8.tar.bz2
scala-231cfbe1c023ccf9e1bc437e5098f41b121fffa8.zip
Closes #3365.
-rw-r--r--src/actors/scala/actors/AbstractActor.scala2
-rw-r--r--src/actors/scala/actors/ActorCanReply.scala2
-rw-r--r--src/actors/scala/actors/CanReply.scala8
-rw-r--r--src/actors/scala/actors/Channel.scala22
-rw-r--r--src/actors/scala/actors/ReactorCanReply.scala6
-rw-r--r--src/actors/scala/actors/remote/Proxy.scala6
-rw-r--r--test/files/jvm/t3365.check5
-rw-r--r--test/files/jvm/t3365.scala65
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
+ }
+}