[Gradle] Share NativeDistributionCommonizerLock with 'cleanNativeDistributionCommonization' task
KT-52172
This commit is contained in:
committed by
Space Team
parent
6e0f5e8212
commit
d12fbcf574
+11
-3
@@ -5,9 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.native.internal
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.tasks.Delete
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.jetbrains.kotlin.compilerRunner.maybeCreateCommonizerClasspathConfiguration
|
||||
import org.jetbrains.kotlin.gradle.internal.isInIdeaSync
|
||||
@@ -140,7 +140,7 @@ internal val Project.commonizeNativeDistributionTask: TaskProvider<NativeDistrib
|
||||
)
|
||||
}
|
||||
|
||||
internal val Project.cleanNativeDistributionCommonizerTask: TaskProvider<Delete>?
|
||||
internal val Project.cleanNativeDistributionCommonizerTask: TaskProvider<DefaultTask>?
|
||||
get() {
|
||||
val commonizeNativeDistributionTask = commonizeNativeDistributionTask ?: return null
|
||||
return rootProject.locateOrRegisterTask(
|
||||
@@ -148,7 +148,15 @@ internal val Project.cleanNativeDistributionCommonizerTask: TaskProvider<Delete>
|
||||
configureTask = {
|
||||
group = "interop"
|
||||
description = "Deletes all previously commonized klib's from the Kotlin/Native distribution"
|
||||
delete(commonizeNativeDistributionTask.map { it.rootOutputDirectory })
|
||||
|
||||
val commonizerDirectory = commonizeNativeDistributionTask.map { it.rootOutputDirectory }
|
||||
outputs.dir(commonizerDirectory)
|
||||
|
||||
doFirst {
|
||||
NativeDistributionCommonizerLock(commonizerDirectory.get()).withLock {
|
||||
delete(commonizerDirectory.get())
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+2
-52
@@ -11,12 +11,8 @@ import org.gradle.api.logging.Logger
|
||||
import org.jetbrains.kotlin.commonizer.*
|
||||
import org.jetbrains.kotlin.commonizer.CommonizerOutputFileLayout.resolveCommonizedDirectory
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.ObjectInputStream
|
||||
import java.io.Serializable
|
||||
import java.util.concurrent.locks.Lock
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
class NativeDistributionCommonizerCache(
|
||||
private val outputDirectory: File,
|
||||
@@ -100,59 +96,13 @@ class NativeDistributionCommonizerCache(
|
||||
* even between multiple process (Gradle Daemons)
|
||||
*/
|
||||
@Transient
|
||||
private var lock = Lock()
|
||||
private var lock = NativeDistributionCommonizerLock(outputDirectory, ::logInfo)
|
||||
|
||||
private fun logInfo(message: String) =
|
||||
logger.info("Native Distribution Commonization: $message")
|
||||
|
||||
private inner class Lock {
|
||||
private val lockedOutputDirectories = mutableSetOf<File>()
|
||||
|
||||
fun <T> withLock(action: () -> T): T {
|
||||
/* Enter intra-process wide lock */
|
||||
intraProcessLock.withLock {
|
||||
if (outputDirectory in lockedOutputDirectories) {
|
||||
/* Already acquired this directory and re-entered: We can just execute the action */
|
||||
return action()
|
||||
}
|
||||
|
||||
/* Lock output directory inter-process wide */
|
||||
outputDirectory.mkdirs()
|
||||
val lockfile = outputDirectory.resolve(".lock")
|
||||
logInfo("Acquire lock: ${lockfile.path} ...")
|
||||
FileOutputStream(outputDirectory.resolve(".lock")).use { stream ->
|
||||
val lock = stream.channel.lock()
|
||||
assert(lock.isValid)
|
||||
return try {
|
||||
logInfo("Lock acquired: ${lockfile.path}")
|
||||
lockedOutputDirectories.add(outputDirectory)
|
||||
action()
|
||||
} finally {
|
||||
lockedOutputDirectories.remove(outputDirectory)
|
||||
lock.release()
|
||||
logInfo("Lock released: ${lockfile.path}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun checkLocked(outputDirectory: File) {
|
||||
check(intraProcessLock.isHeldByCurrentThread) {
|
||||
"Expected lock to be held by current thread ${Thread.currentThread().name}"
|
||||
}
|
||||
|
||||
check(outputDirectory in lockedOutputDirectories) {
|
||||
"Expected $outputDirectory to be locked. Locked directories: $lockedOutputDirectories"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun readObject(input: ObjectInputStream) {
|
||||
input.defaultReadObject()
|
||||
lock = Lock()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
val intraProcessLock: ReentrantLock = ReentrantLock()
|
||||
lock = NativeDistributionCommonizerLock(outputDirectory, ::logInfo)
|
||||
}
|
||||
}
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.targets.native.internal
|
||||
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
import kotlin.concurrent.withLock
|
||||
|
||||
internal class NativeDistributionCommonizerLock(
|
||||
private val outputDirectory: File,
|
||||
private val logInfo: (message: String) -> Unit = {}
|
||||
) {
|
||||
private companion object {
|
||||
val intraProcessLock: ReentrantLock = ReentrantLock()
|
||||
}
|
||||
|
||||
private val lockedOutputDirectories = mutableSetOf<File>()
|
||||
|
||||
fun <T> withLock(action: () -> T): T {
|
||||
/* Enter intra-process wide lock */
|
||||
intraProcessLock.withLock {
|
||||
if (outputDirectory in lockedOutputDirectories) {
|
||||
/* Already acquired this directory and re-entered: We can just execute the action */
|
||||
return action()
|
||||
}
|
||||
|
||||
/* Lock output directory inter-process wide */
|
||||
outputDirectory.mkdirs()
|
||||
val lockfile = outputDirectory.resolve(".lock")
|
||||
logInfo("Acquire lock: ${lockfile.path} ...")
|
||||
FileOutputStream(outputDirectory.resolve(".lock")).use { stream ->
|
||||
val lock = stream.channel.lock()
|
||||
assert(lock.isValid)
|
||||
return try {
|
||||
logInfo("Lock acquired: ${lockfile.path}")
|
||||
lockedOutputDirectories.add(outputDirectory)
|
||||
action()
|
||||
} finally {
|
||||
lockedOutputDirectories.remove(outputDirectory)
|
||||
lock.release()
|
||||
logInfo("Lock released: ${lockfile.path}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun checkLocked(outputDirectory: File) {
|
||||
check(intraProcessLock.isHeldByCurrentThread) {
|
||||
"Expected lock to be held by current thread ${Thread.currentThread().name}"
|
||||
}
|
||||
|
||||
check(outputDirectory in lockedOutputDirectories) {
|
||||
"Expected $outputDirectory to be locked. Locked directories: $lockedOutputDirectories"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user