Move setState from coroutine scope completion handler to network.close, fix #1311

This commit is contained in:
Him188 2021-06-23 15:41:39 +08:00
parent 8d4eb45386
commit 2e47740b1b
3 changed files with 7 additions and 10 deletions

View File

@ -148,6 +148,8 @@ internal interface NetworkHandler : CoroutineScope {
/**
* Closes this handler gracefully (i.e. asynchronously).
*
* After invocation of [close], [state] will always be [State.CLOSED].
*/
fun close(cause: Throwable?)

View File

@ -47,11 +47,6 @@ internal abstract class NetworkHandlerSupport(
}
override fun close(cause: Throwable?) {
// if (cause == null) {
// logger.info { "NetworkHandler '$this' closed" }
// } else {
// logger.info { "NetworkHandler '$this' closed: $cause" }
// }
if (coroutineContext.job.isActive) {
coroutineContext.job.cancel("NetworkHandler closed", cause)
}
@ -202,6 +197,7 @@ internal abstract class NetworkHandlerSupport(
protected data class StateSwitchingException(
val old: BaseStateImpl,
val new: BaseStateImpl,
override val cause: Throwable? = new.getCause(), // so it can be unwrapped
) : CancellationException("State is switched from $old to $new")
/**

View File

@ -195,15 +195,14 @@ internal open class NettyNetworkHandler(
///////////////////////////////////////////////////////////////////////////
override fun close(cause: Throwable?) {
if (state == State.CLOSED) return // already
super.close(cause)
// when coroutine scope completed, state is already set to CLOSED,
// see the following `init` block.
if (state == State.CLOSED) return // quick check if already closed
if (setState { StateClosed(cause) } == null) return // atomic check
super.close(cause) // cancel coroutine scope
}
init {
coroutineContext.job.invokeOnCompletion { e ->
setState { StateClosed(e?.unwrapCancellationException()) }
close(e?.unwrapCancellationException())
}
}