@@ -22,9 +22,15 @@ import kotlin.coroutines.experimental.CoroutineContext
22
22
23
23
/* *
24
24
* Represents common pool of shared threads as coroutine dispatcher for compute-intensive tasks.
25
- * It uses [java.util.concurrent.ForkJoinPool] when available, which implements efficient work-stealing algorithm for its queues, so every
26
- * coroutine resumption is dispatched as a separate task even when it already executes inside the pool.
27
- * When available, it wraps `ForkJoinPool.commonPool` and provides a similar shared pool where not.
25
+ *
26
+ * If there isn't a SecurityManager present it uses [java.util.concurrent.ForkJoinPool] when available, which implements
27
+ * efficient work-stealing algorithm for its queues, so every coroutine resumption is dispatched as a separate task even
28
+ * when it already executes inside the pool. When available, it wraps `ForkJoinPool.commonPool` and provides a similar
29
+ * shared pool where not.
30
+ *
31
+ * If there is a SecurityManager present (as would be if running inside a Java Web Start context) then a plain thread
32
+ * pool is created. This is to work around the fact that ForkJoinPool creates threads that cannot perform
33
+ * privileged actions.
28
34
*/
29
35
object CommonPool : CoroutineDispatcher() {
30
36
private var usePrivatePool = false
@@ -35,6 +41,7 @@ object CommonPool : CoroutineDispatcher() {
35
41
private inline fun <T > Try (block : () -> T ) = try { block() } catch (e: Throwable ) { null }
36
42
37
43
private fun createPool (): ExecutorService {
44
+ if (System .getSecurityManager() != null ) return createPlainPool()
38
45
val fjpClass = Try { Class .forName(" java.util.concurrent.ForkJoinPool" ) }
39
46
? : return createPlainPool()
40
47
if (! usePrivatePool) {
0 commit comments