Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Future.foreach throws scala.actors.SuspendActorControl #5574

Closed
scabug opened this issue Mar 15, 2012 · 6 comments
Closed

Future.foreach throws scala.actors.SuspendActorControl #5574

scabug opened this issue Mar 15, 2012 · 6 comments

Comments

@scabug
Copy link

scabug commented Mar 15, 2012

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: #3458

@scabug
Copy link
Author

scabug commented Mar 15, 2012

Imported From: https://issues.scala-lang.org/browse/SI-5574?orig=1
Reporter: Joseph Shraibman (jks)
Affected Versions: 2.9.1, 2.10.0-M3

@scabug
Copy link
Author

scabug commented Mar 22, 2012

Joseph Shraibman (jks) said:
Setting scala.control.noTraceSuppression and changing suspendException to a def (rather than a val) I get:

scala.actors.SuspendActorControl
        at scala.actors.SuspendActorControl.scala$util$control$NoStackTrace$$super$fillInStackTrace(Actor.scala:872)
        at scala.util.control.NoStackTrace$class.fillInStackTrace(NoStackTrace.scala:21)
        at scala.actors.SuspendActorControl.fillInStackTrace(Actor.scala:872)
        at java.lang.Throwable.<init>(Throwable.java:181)
        at scala.actors.SuspendActorControl.<init>(Actor.scala:872)
        at scala.actors.Actor$.suspendException(Actor.scala:54)
        at scala.actors.Actor$class.searchMailbox(Actor.scala:453)
        at scala.actors.ActorProxy.searchMailbox(ActorProxy.scala:19)
        at scala.actors.Reactor$class.react(Reactor.scala:202)
        at scala.actors.ActorProxy.scala$actors$ReplyReactor$$super$react(ActorProxy.scala:19)
        at scala.actors.ReplyReactor$class.react(ReplyReactor.scala:108)
        at scala.actors.ActorProxy.scala$actors$Actor$$super$react(ActorProxy.scala:19)
        at scala.actors.Actor$class.react(Actor.scala:598)
        at scala.actors.ActorProxy.react(ActorProxy.scala:19)
        at scala.actors.Channel.react(Channel.scala:76)
        at scala.actors.FutureActor.respond(Future.scala:64)
        at scala.Responder.foreach(Responder.scala:71)
        at $line3.$read$$iw$$iw$.liftedTree1$1(<console>:9)
        at $line3.$read$$iw$$iw$.<init>(<console>:9)
        at $line3.$read$$iw$$iw$.<clinit>(<console>)
        at $line3.$eval$.<init>(<console>:7)
        at $line3.$eval$.<clinit>(<console>)
        at $line3.$eval.$print(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:758)
        at scala.tools.nsc.interpreter.IMain$Request$$anonfun$13.apply(IMain.scala:990)
        at scala.tools.nsc.interpreter.Line.scala$tools$nsc$interpreter$Line$$runAndSetState(Line.scala:41)
        at scala.tools.nsc.interpreter.Line$$anonfun$2.apply$mcV$sp(Line.scala:47)
        at scala.tools.nsc.io.package$$anon$2.run(package.scala:19)
        at java.lang.Thread.run(Thread.java:662)

@scabug
Copy link
Author

scabug commented Mar 22, 2012

Joseph Shraibman (jks) said:
Changing suspendException to a def isn't actually necessary. Just starting the repl with -Dscala.control.noTraceSuppression=true is enough.

That stack trace was from the current git head btw. The stack trace generated by 2.9.1 looks slightly different.

@scabug
Copy link
Author

scabug commented Mar 27, 2012

@adriaanm said:
not sure whether this is mostly repl or mostly actor, so, please re-assign if it's mostly REPL

@scabug
Copy link
Author

scabug commented Mar 27, 2012

Joseph Shraibman (jks) said:
I originally encountered this in real code, and this is easy to reproduce with compiled code.

object Temp extends App{

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

}

@scabug
Copy link
Author

scabug commented Dec 13, 2012

@adriaanm said:
actors have migrated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants