summaryrefslogtreecommitdiff
path: root/src/actors
diff options
context:
space:
mode:
authorPhilipp Haller <hallerp@gmail.com>2009-10-09 12:33:31 +0000
committerPhilipp Haller <hallerp@gmail.com>2009-10-09 12:33:31 +0000
commit0e26f93326f7ab25299ae33bd51aae90a320d2cd (patch)
tree931a493da981281ccd9956ea74e34a8ade3cc0fc /src/actors
parent6fb95453d130c5423f0cc2c8b5a6e7108aa4b253 (diff)
downloadscala-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.scala6
-rw-r--r--src/actors/scala/actors/scheduler/DelegatingScheduler.scala17
-rw-r--r--src/actors/scala/actors/scheduler/ForkJoinScheduler.scala4
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) {