Skip to content

Implemented copyForChildCoroutine() for ThreadContextElement #2936

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

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e04fc22
Added CoroutineScope.asExecutor() to ListenableFuture.kt, and used it…
yorickhenning Jun 25, 2019
80568ab
Merge branch 'master' of github.com:Kotlin/kotlinx.coroutines
yorickhenning Aug 30, 2019
702139f
Hid the SettableFuture of future {}.
yorickhenning Sep 3, 2019
e9cae97
Merge branch 'develop' of https://github.com/Kotlin/kotlinx.coroutine…
yorickhenning Apr 14, 2021
f007653
Merge branch 'develop' of github.com:yorickhenning/kotlinx.coroutines…
yorickhenning Sep 9, 2021
fa7daa4
Merge branch 'develop' of github.com:Kotlin/kotlinx.coroutines into d…
yorickhenning Sep 9, 2021
85986c4
Implemented ThreadContextElement.copyForChildCoroutine()
yorickhenning Sep 14, 2021
07a0ab5
Moved `copyForChildCoroutine()` to a `CopyableThreadContextElement`.
yorickhenning Sep 14, 2021
fe562f7
Moved `copyForChildCoroutine()` to a `CopyableThreadContextElement`.
yorickhenning Sep 14, 2021
6a799b3
Moved `copyForChildCoroutine()` to a `CopyableThreadContextElement`.
yorickhenning Sep 14, 2021
9e2f622
Moved `copyForChildCoroutine()` to a `CopyableThreadContextElement`.
yorickhenning Sep 14, 2021
1f1e8a3
Fix benchmarks compilation after migration to Kotlin 1.5.30
qwwdfsad Sep 10, 2021
c69b75c
Add method that allows IDEA debugger to retrieve enhanced stack trace…
nikita-nazarov Sep 20, 2021
91188ea
Update license year in NOTICE.txt
qwwdfsad Sep 21, 2021
83c523f
Promote newSingleThreadContext and newFixedThreadPoolContext to delic…
qwwdfsad Sep 23, 2021
6a99a6d
Cleanup root Gradle script
qwwdfsad Sep 24, 2021
94c6fb7
Add version file to each module resources (#2950)
qwwdfsad Sep 27, 2021
a740994
Migrate from deprecated packages in js-example (#2955)
qwwdfsad Sep 27, 2021
9edeb85
Breaking change: Guava future coroutine builder shouldn't report to C…
vadimsemenov Sep 30, 2021
2cd1011
Update binary compatibility validator (#2969)
qwwdfsad Oct 5, 2021
d014723
Make kotlinx-coroutines-test an MPP (#2965)
dkhalanskyjb Oct 8, 2021
fbbe63b
Implement `setMain` in common code (#2967)
dkhalanskyjb Oct 8, 2021
9dda95a
Promote the following experimental API to stable (#2971)
qwwdfsad Oct 11, 2021
5b4b612
Introduce CoroutineDispatcher.limitedParallelism and make Dispatchers…
qwwdfsad Oct 12, 2021
bd44a94
Eagerly load CoroutineExceptionHandler and load corresponding service…
qwwdfsad Oct 12, 2021
d40f90c
Update Kotlin to 1.6.0-RC (#2980)
qwwdfsad Oct 12, 2021
666354b
Handle exceptions on K/N by invoking 'processUnhandledException' (#2981)
qwwdfsad Oct 13, 2021
13ea81e
Implemented `CopyableThreadContextElement` with a `copyForChildCorout…
yorickhenning Oct 13, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ abstract class ParametrizedDispatcherBase : CoroutineScope {
coroutineContext = when {
dispatcher == "fjp" -> ForkJoinPool.commonPool().asCoroutineDispatcher()
dispatcher == "scheduler" -> {
ExperimentalCoroutineDispatcher(CORES_COUNT).also { closeable = it }
Dispatchers.Default
}
dispatcher.startsWith("ftp") -> {
newFixedThreadPoolContext(dispatcher.substring(4).toInt(), dispatcher).also { closeable = it }
Expand Down
11 changes: 4 additions & 7 deletions benchmarks/src/jmh/kotlin/benchmarks/SemaphoreBenchmark.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ package benchmarks

import benchmarks.common.*
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.scheduling.ExperimentalCoroutineDispatcher
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.sync.*
import org.openjdk.jmh.annotations.*
import java.util.concurrent.ForkJoinPool
import java.util.concurrent.TimeUnit
import java.util.concurrent.*

@Warmup(iterations = 3, time = 500, timeUnit = TimeUnit.MICROSECONDS)
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MICROSECONDS)
Expand Down Expand Up @@ -84,7 +81,7 @@ open class SemaphoreBenchmark {

enum class SemaphoreBenchDispatcherCreator(val create: (parallelism: Int) -> CoroutineDispatcher) {
FORK_JOIN({ parallelism -> ForkJoinPool(parallelism).asCoroutineDispatcher() }),
EXPERIMENTAL({ parallelism -> ExperimentalCoroutineDispatcher(corePoolSize = parallelism, maxPoolSize = parallelism) })
EXPERIMENTAL({ parallelism -> Dispatchers.Default }) // TODO doesn't take parallelism into account
}

private const val WORK_INSIDE = 80
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ open class SequencePlaysScrabble : ShakespearePlaysScrabble() {
val bonusForDoubleLetter: (String) -> Int = { word: String ->
toBeMaxed(word)
.map { letterScores[it - 'a'.toInt()] }
.max()!!
.maxOrNull()!!
}

val score3: (String) -> Int = { word: String ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,8 @@ import kotlin.coroutines.*
@State(Scope.Benchmark)
open class PingPongWithBlockingContext {

@UseExperimental(InternalCoroutinesApi::class)
private val experimental = ExperimentalCoroutineDispatcher(8)
@UseExperimental(InternalCoroutinesApi::class)
private val blocking = experimental.blocking(8)
private val experimental = Dispatchers.Default
private val blocking = Dispatchers.IO.limitedParallelism(8)
private val threadPool = newFixedThreadPoolContext(8, "PongCtx")

@TearDown
Expand Down
100 changes: 69 additions & 31 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@

import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.konan.target.HostManager
import org.gradle.util.VersionNumber
import org.jetbrains.dokka.gradle.DokkaTaskPartial
import org.jetbrains.dokka.gradle.DokkaMultiModuleTask

apply plugin: 'jdk-convention'
apply from: rootProject.file("gradle/opt-in.gradle")

def coreModule = "kotlinx-coroutines-core"
def testModule = "kotlinx-coroutines-test"
def multiplatform = [coreModule, testModule]
// Not applicable for Kotlin plugin
def sourceless = ['kotlinx.coroutines', 'kotlinx-coroutines-bom', 'integration-testing']
def internal = ['kotlinx.coroutines', 'benchmarks', 'integration-testing']
Expand Down Expand Up @@ -47,12 +46,6 @@ buildscript {
}
}

if (using_snapshot_version) {
repositories {
mavenLocal()
}
}

repositories {
mavenCentral()
maven { url "https://plugins.gradle.org/m2/" }
Expand Down Expand Up @@ -102,13 +95,6 @@ allprojects {
kotlin_version = rootProject.properties['kotlin_snapshot_version']
}

if (using_snapshot_version) {
repositories {
mavenLocal()
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
}
}

ext.unpublished = unpublished

// This project property is set during nightly stress test
Expand All @@ -125,7 +111,7 @@ apiValidation {
ignoredProjects += unpublished + ["kotlinx-coroutines-bom"]
if (build_snapshot_train) {
ignoredProjects.remove("example-frontend-js")
ignoredProjects.add("kotlinx-coroutines-core")
ignoredProjects.add(coreModule)
}
ignoredPackages += "kotlinx.coroutines.internal"
}
Expand All @@ -139,19 +125,38 @@ allprojects {
*/
google()
mavenCentral()
maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev" }
}
}

// Add dependency to core source sets. Core is configured in kx-core/build.gradle
configure(subprojects.findAll { !sourceless.contains(it.name) && it.name != coreModule }) {
evaluationDependsOn(":$coreModule")
def platform = PlatformKt.platformOf(it)
apply plugin: "kotlin-${platform}-conventions"
dependencies {
// See comment below for rationale, it will be replaced with "project" dependency
api project(":$coreModule")
// the only way IDEA can resolve test classes
testImplementation project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
if (it.name in multiplatform) {
apply plugin: "kotlin-multiplatform"
apply from: rootProject.file("gradle/compile-jvm-multiplatform.gradle")
apply from: rootProject.file("gradle/compile-common.gradle")

if (rootProject.ext["native_targets_enabled"] as Boolean) {
apply from: rootProject.file("gradle/compile-native-multiplatform.gradle")
}

apply from: rootProject.file("gradle/compile-js-multiplatform.gradle")
apply from: rootProject.file("gradle/publish-npm-js.gradle")
kotlin.sourceSets.commonMain.dependencies {
api project(":$coreModule")
}
kotlin.sourceSets.jvmTest.dependencies {
implementation project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
}
} else {
def platform = PlatformKt.platformOf(it)
apply plugin: "kotlin-${platform}-conventions"
dependencies {
api project(":$coreModule")
// the only way IDEA can resolve test classes
testImplementation project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
}
}
}

Expand All @@ -162,7 +167,7 @@ configure(subprojects.findAll { !sourceless.contains(it.name) }) {

// Configure options for all Kotlin compilation tasks
tasks.withType(org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile).all {
kotlinOptions.freeCompilerArgs += optInAnnotations.collect { "-Xopt-in=" + it }
kotlinOptions.freeCompilerArgs += OptInPresetKt.optInAnnotations.collect { "-Xopt-in=" + it }
kotlinOptions.freeCompilerArgs += "-progressive"
// Disable KT-36770 for RxJava2 integration
kotlinOptions.freeCompilerArgs += "-XXLanguage:-ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated"
Expand All @@ -189,7 +194,7 @@ if (build_snapshot_train) {
}

println "Manifest of kotlin-compiler-embeddable.jar for coroutines"
configure(subprojects.findAll { it.name == "kotlinx-coroutines-core" }) {
configure(subprojects.findAll { it.name == coreModule }) {
configurations.matching { it.name == "kotlinCompilerClasspath" }.all {
resolvedConfiguration.getFiles().findAll { it.name.contains("kotlin-compiler-embeddable") }.each {
def manifest = zipTree(it).matching {
Expand All @@ -206,9 +211,8 @@ if (build_snapshot_train) {

// Redefine source sets because we are not using 'kotlin/main/fqn' folder convention
configure(subprojects.findAll {
!sourceless.contains(it.name) &&
!sourceless.contains(it.name) && !multiplatform.contains(it.name) &&
it.name != "benchmarks" &&
it.name != coreModule &&
it.name != "example-frontend-js"
}) {
// Pure JS and pure MPP doesn't have this notion and are configured separately
Expand Down Expand Up @@ -245,6 +249,40 @@ configure(subprojects.findAll { !unpublished.contains(it.name) }) {
}
}
}

def thisProject = it
if (thisProject.name in sourceless) {
return
}

def versionFileTask = thisProject.tasks.register("versionFileTask") {
def name = thisProject.name.replace("-", "_")
def versionFile = thisProject.layout.buildDirectory.file("${name}.version")
it.outputs.file(versionFile)

it.doLast {
versionFile.get().asFile.text = version.toString()
}
}

List<String> jarTasks
if (it.name in multiplatform) {
jarTasks = ["jvmJar", "metadataJar"]
} else if (it.name == "kotlinx-coroutines-debug") {
// We shadow debug module instead of just packaging it
jarTasks = ["shadowJar"]
} else {
jarTasks = ["jar"]
}

for (name in jarTasks) {
thisProject.tasks.named(name, Jar) {
it.dependsOn versionFileTask
it.from(versionFileTask) {
into("META-INF")
}
}
}
}

// Report Kotlin compiler version when building project
Expand Down Expand Up @@ -302,12 +340,12 @@ allprojects { subProject ->
.matching {
// Excluding substituted project itself because of circular dependencies, but still do it
// for "*Test*" configurations
subProject.name != "kotlinx-coroutines-core" || it.name.contains("Test")
subProject.name != coreModule || it.name.contains("Test")
}
.configureEach { conf ->
conf.resolutionStrategy.dependencySubstitution {
substitute(module("org.jetbrains.kotlinx:kotlinx-coroutines-core"))
.using(project(":kotlinx-coroutines-core"))
substitute(module("org.jetbrains.kotlinx:$coreModule"))
.using(project(":$coreModule"))
.because("Because Kotlin compiler embeddable leaks coroutines into the runtime classpath, " +
"triggering all sort of incompatible class changes errors")
}
Expand Down
13 changes: 13 additions & 0 deletions buildSrc/src/main/kotlin/OptInPreset.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

val optInAnnotations = listOf(
"kotlin.RequiresOptIn",
"kotlin.experimental.ExperimentalTypeInference",
"kotlin.ExperimentalMultiplatform",
"kotlinx.coroutines.DelicateCoroutinesApi",
"kotlinx.coroutines.ExperimentalCoroutinesApi",
"kotlinx.coroutines.ObsoleteCoroutinesApi",
"kotlinx.coroutines.InternalCoroutinesApi",
"kotlinx.coroutines.FlowPreview")
19 changes: 19 additions & 0 deletions buildSrc/src/main/kotlin/SourceSets.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
import org.jetbrains.kotlin.gradle.plugin.*

fun KotlinSourceSet.configureMultiplatform() {
val srcDir = if (name.endsWith("Main")) "src" else "test"
val platform = name.dropLast(4)
kotlin.srcDir("$platform/$srcDir")
if (name == "jvmMain") {
resources.srcDir("$platform/resources")
} else if (name == "jvmTest") {
resources.srcDir("$platform/test-resources")
}
languageSettings {
optInAnnotations.forEach { optIn(it) }
progressiveMode = true
}
}
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Kotlin
version=1.5.2-SNAPSHOT
group=org.jetbrains.kotlinx
kotlin_version=1.5.30
kotlin_version=1.6.0-RC

# Dependencies
junit_version=4.12
Expand All @@ -22,7 +22,7 @@ rxjava2_version=2.2.8
rxjava3_version=3.0.2
javafx_version=11.0.2
javafx_plugin_version=0.0.8
binary_compatibility_validator_version=0.7.0
binary_compatibility_validator_version=0.8.0-RC
blockhound_version=1.0.2.RELEASE
jna_version=5.5.0

Expand Down
2 changes: 1 addition & 1 deletion gradle/dokka.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ tasks.withType(DokkaTaskPartial::class).configureEach {
packageListUrl.set(rootProject.projectDir.toPath().resolve("site/stdlib.package.list").toUri().toURL())
}

if (project.name != "kotlinx-coroutines-core") {
if (project.name != "kotlinx-coroutines-core" && project.name != "kotlinx-coroutines-test") {
dependsOn(project.configurations["compileClasspath"])
doFirst {
// resolve classpath only during execution
Expand Down
13 changes: 0 additions & 13 deletions gradle/opt-in.gradle

This file was deleted.

2 changes: 1 addition & 1 deletion gradle/publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ apply plugin: 'signing'

// ------------- tasks

def isMultiplatform = project.name == "kotlinx-coroutines-core"
def isMultiplatform = project.name == "kotlinx-coroutines-core" || project.name == "kotlinx-coroutines-test"
def isBom = project.name == "kotlinx-coroutines-bom"

if (!isBom) {
Expand Down
1 change: 1 addition & 0 deletions integration-testing/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ task npmTest(type: Test) {
}

task mavenTest(type: Test) {
environment "version", version
def sourceSet = sourceSets.mavenTest
dependsOn(project(':').getTasksByName("publishToMavenLocal", true))
testClassesDirs = sourceSet.output.classesDirs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.junit.*
import org.junit.Assert.assertTrue
import java.util.jar.*

class MavenPublicationValidator {
class MavenPublicationAtomicfuValidator {
private val ATOMIC_FU_REF = "Lkotlinx/atomicfu/".toByteArray()

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.coroutines.validator

import org.junit.*
import org.junit.Test
import java.util.jar.*
import kotlin.test.*

class MavenPublicationVersionValidator {

@Test
fun testMppJar() {
val clazz = Class.forName("kotlinx.coroutines.Job")
JarFile(clazz.protectionDomain.codeSource.location.file).checkForVersion("kotlinx_coroutines_core.version")
}

@Test
fun testAndroidJar() {
val clazz = Class.forName("kotlinx.coroutines.android.HandlerDispatcher")
JarFile(clazz.protectionDomain.codeSource.location.file).checkForVersion("kotlinx_coroutines_android.version")
}

private fun JarFile.checkForVersion(file: String) {
val actualFile = "META-INF/$file"
val version = System.getenv("version")
use {
for (e in entries()) {
if (e.name == actualFile) {
val string = getInputStream(e).readAllBytes().decodeToString()
assertEquals(version, string)
return
}
}
error("File $file not found")
}
}
}
Loading