Skip to content

Commit

Permalink
feat: replace synchronization mechanism with kotlinx.atomicfu locks
Browse files Browse the repository at this point in the history
  • Loading branch information
romainbsl committed Jan 7, 2025
1 parent 7d4d938 commit 33b56c9
Show file tree
Hide file tree
Showing 11 changed files with 29 additions and 19 deletions.
4 changes: 3 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[versions]
# Core
kaverit = "2.10.0"
kaverit = "2.10.0"
atomicfu="0.26.1"
# Android
android-appcompat = "28.0.0"
androidx-appcompat = "1.7.0"
Expand Down Expand Up @@ -64,6 +65,7 @@ junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "jun
junit = { module = "junit:junit", version.ref = "junit" }

[plugins]
kotlinx-atomicfu = { id = "org.jetbrains.kotlinx.atomicfu", version.ref = "atomicfu" }
compose = { id = "org.jetbrains.compose", version.ref = "jbCompose" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
openjfx = { id = "org.openjfx.javafxplugin", version.ref = "openjfx" }
1 change: 1 addition & 0 deletions kodein-di-conf/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id("org.kodein.library.mpp")
alias(libs.plugins.kotlinx.atomicfu)
}

kotlin.kodein {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.kodein.di.conf

import kotlinx.atomicfu.locks.SynchronizedObject
import org.kodein.di.Copy
import org.kodein.di.DI
import org.kodein.di.DIContainer
Expand All @@ -19,7 +20,7 @@ public class ConfigurableDI : DI {
/** @suppress */
override val di: DI get() = this

private val _lock = Any()
private val _lock = SynchronizedObject()

/**
* Whether this Configurabledi can be mutated.
Expand Down
1 change: 1 addition & 0 deletions kodein-di/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
kodein.library.mpp
alias(libs.plugins.kotlinx.atomicfu)
}

kotlin.kodein {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.kodein.di.bindings

import kotlinx.atomicfu.locks.SynchronizedObject
import org.kodein.di.DIContext
import org.kodein.di.DirectDI
import org.kodein.di.internal.maySynchronized
Expand Down Expand Up @@ -53,7 +54,7 @@ public class StandardScopeRegistry : ScopeRegistry() {

private val _cache = newConcurrentMap<RegKey, () -> Any?>()

private val _lock = Any()
private val _lock = SynchronizedObject()

override fun getOrCreate(key: RegKey, sync: Boolean, creator: () -> Reference<Any>): Any {
return synchronizedIfNull(
Expand Down Expand Up @@ -107,7 +108,7 @@ public class StandardScopeRegistry : ScopeRegistry() {
* If the key changes, the held item will be replaced.
*/
public class SingleItemScopeRegistry : ScopeRegistry() {
private val _lock = Any()
private val _lock = SynchronizedObject()

@kotlin.concurrent.Volatile
private var _pair: Pair<RegKey, () -> Any?>? = null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.kodein.di.bindings

import kotlinx.atomicfu.locks.SynchronizedObject
import org.kodein.di.*
import org.kodein.di.internal.BindingDIImpl
import org.kodein.di.internal.synchronizedIfNull
Expand Down Expand Up @@ -199,7 +200,7 @@ public class EagerSingleton<T : Any>(

@Volatile
private var _instance: T? = null
private val _lock = Any()
private val _lock = SynchronizedObject()

private fun getFactory(di: BindingDI<Any>): (Unit) -> T {
return { _ ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.kodein.di.internal

import kotlinx.atomicfu.locks.SynchronizedObject
import org.kodein.di.AnyDIContext
import org.kodein.di.BindingsMap
import org.kodein.di.DI
Expand Down Expand Up @@ -43,7 +44,7 @@ internal class DIContainerImpl private constructor(
if (runCallbacks)
init()
else {
val lock = Any()
val lock = SynchronizedObject()
initCallbacks = {
synchronizedIfNotNull(
lock = lock,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
package org.kodein.di.internal

public expect inline fun <R> maySynchronized(lock: Any?, block: () -> R): R
import kotlinx.atomicfu.locks.SynchronizedObject
import kotlinx.atomicfu.locks.synchronized

/**
* Using kotlinx-atomicfu may cause some performance issues on native platforms.
* @see https://youtrack.jetbrains.com/issue/CMP-1182 and https://youtrack.jetbrains.com/issue/KT-70751
*/
public inline fun <R> maySynchronized(lock: SynchronizedObject?, block: () -> R): R =
if (lock == null) {
block()
} else {
synchronized(lock, block)
}

/** @suppress */
public inline fun <T: Any, R> synchronizedIfNull(lock: Any?, predicate: () -> T?, ifNotNull: (T) -> R, ifNull: () -> R): R {
public inline fun <T: Any, R> synchronizedIfNull(lock: SynchronizedObject?, predicate: () -> T?, ifNotNull: (T) -> R, ifNull: () -> R): R {
predicate()?.let {
return ifNotNull(it)
}
Expand All @@ -18,7 +30,7 @@ public inline fun <T: Any, R> synchronizedIfNull(lock: Any?, predicate: () -> T?
}

/** @suppress */
internal inline fun <T: Any, R> synchronizedIfNotNull(lock: Any?, predicate: () -> T?, ifNull: () -> R, ifNotNull: (T) -> R): R {
internal inline fun <T: Any, R> synchronizedIfNotNull(lock: SynchronizedObject?, predicate: () -> T?, ifNull: () -> R, ifNotNull: (T) -> R): R {
if (predicate() == null) {
return ifNull()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@ package org.kodein.di.internal
internal actual fun <K, V> newConcurrentMap(): MutableMap<K, V> = HashMap()
internal actual fun <T> newLinkedList(): MutableList<T> = ArrayList()
internal actual fun <T> newLinkedList(c: Collection<T>): MutableList<T> = ArrayList(c)

public actual inline fun <R> maySynchronized(lock: Any?, block: () -> R): R = block()
6 changes: 0 additions & 6 deletions kodein-di/src/jvmMain/kotlin/org/kodein/di/internal/lang.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,3 @@ import java.util.concurrent.ConcurrentHashMap
internal actual fun <K, V> newConcurrentMap(): MutableMap<K, V> = ConcurrentHashMap()
internal actual fun <T> newLinkedList(): MutableList<T> = LinkedList()
internal actual fun <T> newLinkedList(c: Collection<T>): MutableList<T> = LinkedList(c)

public actual inline fun <R> maySynchronized(lock: Any?, block: () -> R): R =
if (lock == null)
block()
else
synchronized(lock, block)
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@ package org.kodein.di.internal
internal actual fun <K, V> newConcurrentMap(): MutableMap<K, V> = HashMap()
internal actual fun <T> newLinkedList(): MutableList<T> = ArrayList()
internal actual fun <T> newLinkedList(c: Collection<T>): MutableList<T> = ArrayList(c)

public actual inline fun <R> maySynchronized(lock: Any?, block: () -> R): R = block()

0 comments on commit 33b56c9

Please sign in to comment.