forked from Kotlin/kotlinx.coroutines
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement permit release also for LimitedDispatcher
PermitTransfer is extracted to be used both in CoroutineScheduler and in LimitedDispatcher. BlockingDispatchAware interface is introduced for LimitedDispatcher.Worker to be accounted by CoroutineScheduler. Kotlin#3983 / IJPL-721
- Loading branch information
1 parent
f54d9d0
commit 275a0ad
Showing
9 changed files
with
184 additions
and
33 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
kotlinx-coroutines-core/common/src/internal/BlockingDispatchAware.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package kotlinx.coroutines.internal | ||
|
||
|
||
internal interface BlockingDispatchAware { | ||
fun beforeDispatchElsewhere() | ||
fun afterDispatchBack() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
kotlinx-coroutines-core/common/src/internal/PermitTransfer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package kotlinx.coroutines.internal | ||
|
||
import kotlinx.atomicfu.* | ||
import kotlin.jvm.* | ||
|
||
@JvmField | ||
internal val PERMIT_ACQUIRE_PARK_NS = systemProp( | ||
"kotlinx.coroutines.permit.acquire.ns", 250L * 1000 * 1000 // 250ms | ||
) | ||
|
||
internal class PermitTransferStatus { | ||
private val status = atomic(false) | ||
fun check(): Boolean = status.value | ||
fun complete(): Boolean = status.compareAndSet(false, true) | ||
} | ||
|
||
internal expect class PermitTransfer constructor() { | ||
/** | ||
* [releasePermit] may throw | ||
*/ | ||
fun releaseFun(releasePermit: () -> Unit): () -> Unit | ||
|
||
/** | ||
* [tryAllocatePermit] and [deallocatePermit] must not throw | ||
*/ | ||
fun acquire(tryAllocatePermit: () -> Boolean, deallocatePermit: () -> Unit) | ||
} | ||
|
||
internal class BusyPermitTransfer { | ||
private val status = PermitTransferStatus() | ||
|
||
fun releaseFun(releasePermit: () -> Unit): () -> Unit = { | ||
if (status.complete()) { | ||
releasePermit() | ||
} | ||
} | ||
|
||
fun acquire(tryAllocatePermit: () -> Boolean, deallocatePermit: () -> Unit) { | ||
while (true) { | ||
if (status.check()) { | ||
return | ||
} | ||
if (tryAllocatePermit()) { | ||
if (!status.complete()) { // race: transfer was completed first by releaseFun | ||
deallocatePermit() | ||
} | ||
return | ||
} | ||
} | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
kotlinx-coroutines-core/jsAndWasmShared/src/internal/PermitTransfer.jsAndWasmShared.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package kotlinx.coroutines.internal | ||
|
||
internal actual typealias PermitTransfer = BusyPermitTransfer // TODO |
37 changes: 37 additions & 0 deletions
37
kotlinx-coroutines-core/jvm/src/internal/PermitTransfer.jvm.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package kotlinx.coroutines.internal | ||
|
||
import java.util.concurrent.locks.* | ||
|
||
internal actual class PermitTransfer { | ||
private val status = PermitTransferStatus() | ||
|
||
public actual fun releaseFun(releasePermit: () -> Unit): () -> Unit { | ||
val blockedThread = Thread.currentThread() | ||
return { | ||
if (status.complete()) { | ||
try { | ||
releasePermit() | ||
} finally { | ||
LockSupport.unpark(blockedThread) | ||
} | ||
} | ||
} | ||
} | ||
|
||
public actual fun acquire(tryAllocatePermit: () -> Boolean, deallocatePermit: () -> Unit) { | ||
while (true) { | ||
if (status.check()) { | ||
return | ||
} | ||
if (tryAllocatePermit()) { | ||
if (!status.complete()) { // race: transfer was completed first by releaseFun | ||
deallocatePermit() | ||
} | ||
return | ||
} | ||
LockSupport.parkNanos( | ||
PERMIT_ACQUIRE_PARK_NS // todo: not sure if it's needed at all, I mean that it is < Long.MAX_VALUE, but at least this way it's safer | ||
) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
kotlinx-coroutines-core/native/src/internal/PermitTransfer.native.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package kotlinx.coroutines.internal | ||
|
||
internal actual typealias PermitTransfer = BusyPermitTransfer // TODO |