Uploaded image for project: 'Scala Programming Language'
  1. Scala Programming Language
  2. SI-5574

Future.foreach throws scala.actors.SuspendActorControl

    Details

      Description

      Minimized test-case:

      object Temp extends App{
        val fut = scala.actors.Futures.future({ Thread.sleep(1000) ; 1 + 1 })
        fut.foreach( println _ )
      }
       
      $ scala -cp . t5574.scala
      scala.actors.SuspendActorControl
      


      Old description follows.

      Doing this in the repl:

      val fut = scala.actors.Futures.future({ Thread.sleep(1000) ; 1 + 1 })
      fut.foreach( println _ )
      

      results in:

       scala.actors.ActorProxy@5629fbc9: caught java.lang.InterruptedException
      java.lang.InterruptedException
              at scala.actors.ActorProxy.exit(ActorProxy.scala:32)
              at scala.actors.Reactor$$anonfun$2.apply(Reactor.scala:267)
              at scala.actors.Reactor$$anonfun$2.apply(Reactor.scala:267)
              at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
              at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
              at scala.actors.ReactorTask.run(ReactorTask.scala:41)
              at scala.actors.Reactor$class.resumeReceiver(Reactor.scala:129)
              at scala.actors.ActorProxy.scala$actors$ReplyReactor$$super$resumeReceiver(ActorProxy.scala:20)
              at scala.actors.ReplyReactor$class.resumeReceiver(ReplyReactor.scala:68)
              at scala.actors.ActorProxy.resumeReceiver(ActorProxy.scala:20)
              at scala.actors.Actor$class.searchMailbox(Actor.scala:500)
              at scala.actors.ActorProxy.searchMailbox(ActorProxy.scala:20)
              at scala.actors.Reactor$$anonfun$startSearch$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(Reactor.scala:117)
              at scala.actors.Reactor$$anonfun$startSearch$1$$anonfun$apply$mcV$sp$1.apply(Reactor.scala:114)
              at scala.actors.Reactor$$anonfun$startSearch$1$$anonfun$apply$mcV$sp$1.apply(Reactor.scala:114)
              at scala.actors.ReactorTask.run(ReactorTask.scala:33)
              at scala.concurrent.forkjoin.ForkJoinPool$AdaptedRunnable.exec(ForkJoinPool.java:611)
              at scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422)
              at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340)
              at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325)
      

      Problem was mentioned here: http://www.scala-lang.org/node/9298

      I think the problem is this:

      foreach defined in scala.Responder:

      def foreach(k: A => Unit) { respond(k) }
      

      Future respond() is:

        def respond(k: T => Unit) {
          if (isSet) k(fvalueTyped)
          else {
            val ft = this !! Eval
            ft.inputChannel.react {
              case _ => k(fvalueTyped)
            }
          }
        }
      

      When the Future is not set foreach calls react on the input channel, which calls react back on the future. In Reactor.scala line 200:

       protected def react(handler: PartialFunction[Msg, Unit]): Nothing = {
          synchronized { drainSendBuffer(mailbox) }
          searchMailbox(mailbox, handler, false)
          throw Actor.suspendException
        }
      

      See also: https://issues.scala-lang.org/browse/SI-3458

        Attachments

          Activity

            People

            • Assignee:
              phaller Philipp Haller
              Reporter:
              jks Joseph Shraibman
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: