From 4a062698f229f7afb95a1dc25d777dc4df1a4e6d Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Fri, 25 Sep 2015 03:59:43 +0300 Subject: [PATCH] Introduce final field in SynchronizedLazyImpl to enable safe publication. --- libraries/stdlib/src/kotlin/util/Lazy.kt | 7 ++----- libraries/stdlib/src/kotlin/util/LazyJVM.kt | 10 +++------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/libraries/stdlib/src/kotlin/util/Lazy.kt b/libraries/stdlib/src/kotlin/util/Lazy.kt index f04e842e06b..062fc50cc00 100644 --- a/libraries/stdlib/src/kotlin/util/Lazy.kt +++ b/libraries/stdlib/src/kotlin/util/Lazy.kt @@ -54,11 +54,10 @@ public enum class LazyThreadSafetyMode { private object UNINITIALIZED_VALUE -internal open class LazyImpl(initializer: () -> T) : Lazy(), Serializable { +internal class SynchronizedLazyImpl(initializer: () -> T, lock: Any? = null) : Lazy(), Serializable { private var initializer: (() -> T)? = initializer @Volatile private var _value: Any? = UNINITIALIZED_VALUE - protected open val lock: Any - get() = this + private val lock = lock ?: this override val value: T get() { @@ -88,8 +87,6 @@ internal open class LazyImpl(initializer: () -> T) : Lazy(), Serializa private fun writeReplace(): Any = InitializedLazyImpl(value) } -internal class ExternallySynchronizedLazyImpl(override val lock: Any, initializer: () -> T): LazyImpl(initializer) - internal class UnsafeLazyImpl(initializer: () -> T) : Lazy(), Serializable { private var initializer: (() -> T)? = initializer private var _value: Any? = UNINITIALIZED_VALUE diff --git a/libraries/stdlib/src/kotlin/util/LazyJVM.kt b/libraries/stdlib/src/kotlin/util/LazyJVM.kt index 81395d3119d..39a087eb3e1 100644 --- a/libraries/stdlib/src/kotlin/util/LazyJVM.kt +++ b/libraries/stdlib/src/kotlin/util/LazyJVM.kt @@ -13,7 +13,7 @@ package kotlin * Note that the returned instance uses itself to synchronize on. Do not synchronize from external code on * the returned instance as it may cause accidental deadlock. Also this behavior can be changed in the future. */ -public fun lazy(initializer: () -> T): Lazy = LazyImpl(initializer) +public fun lazy(initializer: () -> T): Lazy = SynchronizedLazyImpl(initializer) /** * Creates a new instance of the [Lazy] that uses the specified initialization function [initializer] @@ -27,7 +27,7 @@ public fun lazy(initializer: () -> T): Lazy = LazyImpl(initializer) */ public fun lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy = when (mode) { - LazyThreadSafetyMode.SYNCHRONIZED -> LazyImpl(initializer) + LazyThreadSafetyMode.SYNCHRONIZED -> SynchronizedLazyImpl(initializer) LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer) } @@ -42,8 +42,4 @@ public fun lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy = * in this case do not synchronize from external code on the returned instance as it may cause accidental deadlock. * Also this behavior can be changed in the future. */ -public fun lazy(lock: Any?, initializer: () -> T): Lazy = - if (lock != null) - ExternallySynchronizedLazyImpl(lock, initializer) - else - LazyImpl(initializer) \ No newline at end of file +public fun lazy(lock: Any?, initializer: () -> T): Lazy = SynchronizedLazyImpl(initializer, lock)