diff --git a/arrow-libs/core/arrow-autoclose/src/commonMain/kotlin/arrow/AutoCloseScope.kt b/arrow-libs/core/arrow-autoclose/src/commonMain/kotlin/arrow/AutoCloseScope.kt index 9f8f45fcecd..72d6671e688 100644 --- a/arrow-libs/core/arrow-autoclose/src/commonMain/kotlin/arrow/AutoCloseScope.kt +++ b/arrow-libs/core/arrow-autoclose/src/commonMain/kotlin/arrow/AutoCloseScope.kt @@ -2,7 +2,6 @@ package arrow import arrow.atomic.Atomic import arrow.atomic.update -import arrow.atomic.value import kotlin.coroutines.cancellation.CancellationException /** @@ -97,7 +96,7 @@ internal class DefaultAutoCloseScope : AutoCloseScope { } fun close(error: Throwable?): Nothing? { - return finalizers.value.asReversed().fold(error) { acc, finalizer -> + return finalizers.getAndSet(emptyList()).asReversed().fold(error) { acc, finalizer -> acc.add(runCatching { finalizer(error) }.exceptionOrNull()) }?.let { throw it } } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Resource.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Resource.kt index a220f0b8c07..d14d86dd3b4 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Resource.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonMain/kotlin/arrow/fx/coroutines/Resource.kt @@ -3,7 +3,6 @@ package arrow.fx.coroutines import arrow.AutoCloseScope import arrow.atomic.Atomic import arrow.atomic.update -import arrow.atomic.value import arrow.core.nonFatalOrThrow import arrow.core.prependTo import kotlinx.coroutines.CoroutineDispatcher @@ -471,7 +470,7 @@ internal class ResourceScopeImpl : ResourceScope { suspend fun cancelAll(exitCase: ExitCase) { withContext(NonCancellable) { - finalizers.value.fold(exitCase.errorOrNull) { acc, finalizer -> + finalizers.getAndSet(emptyList()).fold(exitCase.errorOrNull) { acc, finalizer -> acc.add(runCatching { finalizer(exitCase) }.exceptionOrNull()) } }?.let { throw it } diff --git a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ResourceTest.kt b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ResourceTest.kt index 5ac980fbd46..cd7dce8c828 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ResourceTest.kt +++ b/arrow-libs/fx/arrow-fx-coroutines/src/commonTest/kotlin/arrow/fx/coroutines/ResourceTest.kt @@ -699,6 +699,21 @@ class ResourceTest { } } + @OptIn(DelicateCoroutinesApi::class) + @Test + fun allocatedRunsReleasersOnlyOnce() = runTest { + val released = CompletableDeferred() + val (_, release) = + resource { + onRelease { exitCase -> + require(released.complete(exitCase)) + } + }.allocate() + release(ExitCase.Completed) + release(ExitCase.Completed) + released.shouldHaveCompleted() shouldBe ExitCase.Completed + } + private class Res : AutoCloseable { private val isActive = AtomicBoolean(true)