diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-11-06 22:48:57 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-11-06 22:48:57 +1000 |
commit | c12a9b7bf8dc423783dd02eb0e4c477c86de96df (patch) | |
tree | 4a7f34cc8f67ed6e4a86f79cf4e0fbd6682fc317 | |
parent | 4059d76dd9240f365712a79ba086f70f2eb8be9b (diff) | |
parent | 9273c333b536e45d561dd9798e88545794459b7c (diff) | |
download | scala-c12a9b7bf8dc423783dd02eb0e4c477c86de96df.tar.gz scala-c12a9b7bf8dc423783dd02eb0e4c477c86de96df.tar.bz2 scala-c12a9b7bf8dc423783dd02eb0e4c477c86de96df.zip |
Merge pull request #4090 from retronym/ticket/8955
SI-8955 Fix hanging fork-join pool via parallel collections
-rw-r--r-- | src/library/scala/concurrent/impl/ExecutionContextImpl.scala | 12 | ||||
-rw-r--r-- | test/files/run/t8955.scala | 12 |
2 files changed, 21 insertions, 3 deletions
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala index 32f30b9049..0c7f98ce5a 100644 --- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala +++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala @@ -101,20 +101,26 @@ private[concurrent] object ExecutionContextImpl { } def range(floor: Int, desired: Int, ceiling: Int) = scala.math.min(scala.math.max(floor, desired), ceiling) - + val numThreads = getInt("scala.concurrent.context.numThreads", "x1") + // The hard limit on the number of active threads that the thread factory will produce + // SI-8955 Deadlocks can happen if maxNoOfThreads is too low, although we're currently not sure + // about what the exact threshhold is. numThreads + 256 is conservatively high. val maxNoOfThreads = getInt("scala.concurrent.context.maxThreads", "x1") val desiredParallelism = range( getInt("scala.concurrent.context.minThreads", "1"), - getInt("scala.concurrent.context.numThreads", "x1"), + numThreads, maxNoOfThreads) + // The thread factory must provide additional threads to support managed blocking. + val maxExtraThreads = getInt("scala.concurrent.context.maxExtraThreads", "256") + val uncaughtExceptionHandler: Thread.UncaughtExceptionHandler = new Thread.UncaughtExceptionHandler { override def uncaughtException(thread: Thread, cause: Throwable): Unit = reporter(cause) } val threadFactory = new ExecutionContextImpl.DefaultThreadFactory(daemonic = true, - maxThreads = maxNoOfThreads, + maxThreads = maxNoOfThreads + maxExtraThreads, prefix = "scala-execution-context-global", uncaught = uncaughtExceptionHandler) diff --git a/test/files/run/t8955.scala b/test/files/run/t8955.scala new file mode 100644 index 0000000000..afa31aa5d7 --- /dev/null +++ b/test/files/run/t8955.scala @@ -0,0 +1,12 @@ +import scala.collection.parallel.immutable.ParSet + +object Test { + def main(args: Array[String]): Unit = { + for (i <- 1 to 2000) test() + } + + def test() { + ParSet[Int]((1 to 10000): _*) foreach (x => ()) // hangs non deterministically + } +} + |