diff options
author | Philipp Haller <hallerp@gmail.com> | 2009-10-09 12:33:31 +0000 |
---|---|---|
committer | Philipp Haller <hallerp@gmail.com> | 2009-10-09 12:33:31 +0000 |
commit | 0e26f93326f7ab25299ae33bd51aae90a320d2cd (patch) | |
tree | 931a493da981281ccd9956ea74e34a8ade3cc0fc /src/actors | |
parent | 6fb95453d130c5423f0cc2c8b5a6e7108aa4b253 (diff) | |
download | scala-0e26f93326f7ab25299ae33bd51aae90a320d2cd.tar.gz scala-0e26f93326f7ab25299ae33bd51aae90a320d2cd.tar.bz2 scala-0e26f93326f7ab25299ae33bd51aae90a320d2cd.zip |
Fix for a race condition when starting an Actor...
Fix for a race condition when starting an Actor while its
ForkJoinScheduler is shutting down.
Diffstat (limited to 'src/actors')
-rw-r--r-- | src/actors/scala/actors/Actor.scala | 6 | ||||
-rw-r--r-- | src/actors/scala/actors/scheduler/DelegatingScheduler.scala | 17 | ||||
-rw-r--r-- | src/actors/scala/actors/scheduler/ForkJoinScheduler.scala | 4 |
3 files changed, 21 insertions, 6 deletions
diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala index 366141f33b..2adf3f5ffd 100644 --- a/src/actors/scala/actors/Actor.scala +++ b/src/actors/scala/actors/Actor.scala @@ -686,10 +686,8 @@ trait Actor extends AbstractActor with ReplyReactor with ReplyableActor { exiting = false shouldExit = false - scheduler execute { - scheduler.newActor(Actor.this) - (new Reaction(Actor.this)).run() - } + scheduler.newActor(this) + scheduler.execute(new Reaction(this)) this } diff --git a/src/actors/scala/actors/scheduler/DelegatingScheduler.scala b/src/actors/scala/actors/scheduler/DelegatingScheduler.scala index b25e3d26f5..434911c48d 100644 --- a/src/actors/scala/actors/scheduler/DelegatingScheduler.scala +++ b/src/actors/scala/actors/scheduler/DelegatingScheduler.scala @@ -48,7 +48,22 @@ private[actors] trait DelegatingScheduler extends IScheduler { } } - def newActor(actor: Reactor) = impl.newActor(actor) + def newActor(actor: Reactor) = synchronized { + val createNew = if (sched eq null) + true + else sched.synchronized { + if (!sched.isActive) + true + else { + sched.newActor(actor) + false + } + } + if (createNew) { + sched = makeNewScheduler() + sched.newActor(actor) + } + } def terminated(actor: Reactor) = impl.terminated(actor) diff --git a/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala b/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala index 86fb14db50..b0198d4879 100644 --- a/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala +++ b/src/actors/scala/actors/scheduler/ForkJoinScheduler.scala @@ -69,6 +69,7 @@ class ForkJoinScheduler(val initCoreSize: Int, val maxSize: Int, daemon: Boolean if (allTerminated) { Debug.info(this+": all actors terminated") + terminating = true throw new QuitException } @@ -79,6 +80,7 @@ class ForkJoinScheduler(val initCoreSize: Int, val maxSize: Int, daemon: Boolean val num = pool.drainTasksTo(list) Debug.info(this+": drained "+num+" tasks") drainedTasks = list + terminating = true throw new QuitException } } @@ -127,7 +129,7 @@ class ForkJoinScheduler(val initCoreSize: Int, val maxSize: Int, daemon: Boolean } def isActive = synchronized { - (pool ne null) && !pool.isShutdown() + !terminating && (pool ne null) && !pool.isShutdown() } override def managedBlock(blocker: scala.concurrent.ManagedBlocker) { |