From a52f80c4e867e5ae0a0d6fb6676b7fee127ff8b4 Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Wed, 21 Jun 2017 17:00:23 +0700 Subject: [PATCH] dependencies: Release file lock if an exception is thrown --- .../src/main/kotlin/DependencyDownloader.kt | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/tools/helpers/src/main/kotlin/DependencyDownloader.kt b/tools/helpers/src/main/kotlin/DependencyDownloader.kt index a4bc0f84123..1f07b8ff618 100644 --- a/tools/helpers/src/main/kotlin/DependencyDownloader.kt +++ b/tools/helpers/src/main/kotlin/DependencyDownloader.kt @@ -20,7 +20,9 @@ import java.io.* import java.net.URL import java.nio.file.Files import java.nio.file.StandardCopyOption +import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.thread +import kotlin.concurrent.withLock // TODO: Try to use some dependency management system (Ivy?) class DependencyDownloader(dependenciesRoot: File, val dependenciesUrl: String, val dependencies: List) { @@ -172,11 +174,34 @@ class DependencyDownloader(dependenciesRoot: File, val dependenciesUrl: String, ) } - fun run() { - val systemLock = RandomAccessFile(lockFile, "rw").channel.lock() - dependencies.forEach { - processDependency(it) + // stdlib `use` function adapted for AutoCloseable. + private inline fun T.use(block: (T) -> R): R { + var closed = false + try { + return block(this) + } catch (e: Exception) { + closed = true + try { + this?.close() + } catch (closeException: Exception) { + } + throw e + } finally { + if (!closed) { + this?.close() + } + } + } + + companion object { + val lock = ReentrantLock() + } + + fun run() = lock.withLock { + RandomAccessFile(lockFile, "rw").channel.lock().use { + dependencies.forEach { + processDependency(it) + } } - systemLock.release() } }