Introduce NamedMutex
Maybe we should have a better impl?
This commit is contained in:
1 parent
18c205dde2
commit
3762b69fed
2 files changed
+33
-4
No files matched your search
@@ -34,10 +34,10 @@ import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import moe.tarsin.coroutines.NamedMutex
|
||||
import moe.tarsin.coroutines.withLock
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
class ArchivePageLoader(context: Context, private val uri: Uri, passwdFlow: Flow<String>) : PageLoader2(), CoroutineScope {
|
||||
@@ -79,7 +79,7 @@ class ArchivePageLoader(context: Context, private val uri: Uri, passwdFlow: Flow
|
||||
}
|
||||
|
||||
private val mJobMap = hashMapOf<Int, Job>()
|
||||
private val mWorkerMutex by lazy { (0 until size).map { Mutex() } }
|
||||
private val mWorkerMutex = NamedMutex<Int>()
|
||||
private val mSemaphore = Semaphore(4)
|
||||
|
||||
override fun onRequest(index: Int) {
|
||||
@@ -87,7 +87,7 @@ class ArchivePageLoader(context: Context, private val uri: Uri, passwdFlow: Flow
|
||||
val current = mJobMap[index]
|
||||
if (current?.isActive != true) {
|
||||
mJobMap[index] = launch {
|
||||
mWorkerMutex[index].withLock {
|
||||
mWorkerMutex.withLock(index) {
|
||||
mSemaphore.withPermit {
|
||||
doRealWork(index)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package moe.tarsin.coroutines
|
||||
|
||||
import arrow.core.memoize
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
class NamedMutex<T> {
|
||||
val innerMutexGetter = { _: T -> Mutex() }.memoize()
|
||||
}
|
||||
|
||||
suspend inline fun <T, K> NamedMutex<K>.withLock(key: K, owner: Any? = null, action: () -> T): T {
|
||||
contract {
|
||||
callsInPlace(action, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
val mutex = synchronized(innerMutexGetter) {
|
||||
innerMutexGetter(key)
|
||||
}
|
||||
|
||||
mutex.run {
|
||||
lock(owner)
|
||||
try {
|
||||
return action()
|
||||
} finally {
|
||||
unlock(owner)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user