diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e7f39d5e4a..08ca25b37c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ * `Versions` * `Exposed`: `0.31.1` -> `0.32.1` +* `Coroutines` + * `JVM` + * `launchSynchronously` and subsequent functions got improved mechanism ## 0.5.5 diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt index f84e6cdb8e1..4714210efb4 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/HandleSafely.kt @@ -115,6 +115,12 @@ suspend inline fun runCatchingSafely( safely(onException, block) } +suspend inline fun safelyWithResult( + noinline block: suspend CoroutineScope.() -> T +): Result = runCatching { + safely({ throw it }, block) +} + /** * Use this handler in cases you wish to include handling of exceptions by [defaultSafelyWithoutExceptionHandler] and * returning null at one time diff --git a/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt index d5142fcba7f..e4fb735da36 100644 --- a/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt +++ b/coroutines/src/jvmMain/kotlin/dev/inmo/micro_utils/coroutines/LaunchSynchronously.kt @@ -3,27 +3,21 @@ package dev.inmo.micro_utils.coroutines import kotlinx.coroutines.* fun CoroutineScope.launchSynchronously(block: suspend CoroutineScope.() -> T): T { - val deferred = CompletableDeferred() - val objectToSynchronize = java.lang.Object() - val launchCallback = { + var result: Result? = null + val objectToSynchronize = Object() + synchronized(objectToSynchronize) { launch { - safely( - { - deferred.completeExceptionally(it) - } - ) { - deferred.complete(block()) - } + result = safelyWithResult(block) + }.invokeOnCompletion { synchronized(objectToSynchronize) { objectToSynchronize.notifyAll() } } + while (result == null) { + objectToSynchronize.wait() + } } - synchronized(objectToSynchronize) { - launchCallback() - objectToSynchronize.wait() - } - return deferred.getCompleted() + return result!!.getOrThrow() } fun launchSynchronously(block: suspend CoroutineScope.() -> T): T = CoroutineScope(Dispatchers.Default).launchSynchronously(block)