From 57167922e22c67698cfb1c0dfdb2d4e770e1dc62 Mon Sep 17 00:00:00 2001 From: Georgy Bronnikov Date: Wed, 13 Jan 2021 17:59:52 +0300 Subject: [PATCH] IR: make lazyVar synchronized --- .../kotlin/ir/declarations/lazy/lazyUtil.kt | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/lazyUtil.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/lazyUtil.kt index 79d9135a90f..7551d6f9205 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/lazyUtil.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/lazyUtil.kt @@ -8,22 +8,30 @@ package org.jetbrains.kotlin.ir.declarations.lazy import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty -fun lazyVar(initializer: () -> T): ReadWriteProperty = UnsafeLazyVar(initializer) +fun lazyVar(initializer: () -> T): ReadWriteProperty = SynchronizedLazyVar(initializer) -private class UnsafeLazyVar(initializer: () -> T) : ReadWriteProperty { +private class SynchronizedLazyVar(initializer: () -> T) : ReadWriteProperty { + @Volatile private var isInitialized = false + private var initializer: (() -> T)? = initializer + + @Volatile private var _value: Any? = null private val value: T get() { - if (!isInitialized) { - _value = initializer!!() - isInitialized = true - initializer = null - } @Suppress("UNCHECKED_CAST") - return _value as T + if (isInitialized) return _value as T + synchronized(this) { + if (!isInitialized) { + _value = initializer!!() + isInitialized = true + initializer = null + } + @Suppress("UNCHECKED_CAST") + return _value as T + } } override fun toString(): String = if (isInitialized) value.toString() else "Lazy value not initialized yet." @@ -31,7 +39,9 @@ private class UnsafeLazyVar(initializer: () -> T) : ReadWriteProperty): T = value override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { - this._value = value - isInitialized = true + synchronized(this) { + this._value = value + isInitialized = true + } } }