locks support
This commit is contained in:
@@ -0,0 +1,77 @@
|
|||||||
|
package std.concurrent
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.Lock
|
||||||
|
import java.util.concurrent.locks.ReadWriteLock
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock
|
||||||
|
|
||||||
|
/*
|
||||||
|
Executes given calculation under lock
|
||||||
|
Returns result of the calculation
|
||||||
|
*/
|
||||||
|
inline fun <erased T> Lock.withLock(action: ()->T) : T {
|
||||||
|
lock()
|
||||||
|
try {
|
||||||
|
return action()
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Executes given calculation under read lock
|
||||||
|
Returns result of the calculation
|
||||||
|
*/
|
||||||
|
inline fun <erased T> ReentrantReadWriteLock.read(action: ()->T) : T {
|
||||||
|
val rl = readLock().sure()
|
||||||
|
rl.lock()
|
||||||
|
try {
|
||||||
|
return action()
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
rl.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Executes given calculation under write lock doing upgrade from read lock if needed
|
||||||
|
Returns result of the calculation
|
||||||
|
*/
|
||||||
|
inline fun <erased T> ReentrantReadWriteLock.write(action: ()->T) : T {
|
||||||
|
val rl = readLock().sure()
|
||||||
|
var upgradeCount = getWriteHoldCount()
|
||||||
|
if(upgradeCount == 0) {
|
||||||
|
upgradeCount = getReadHoldCount()
|
||||||
|
if(upgradeCount > 0)
|
||||||
|
rl.unlock(upgradeCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
val wl = writeLock().sure()
|
||||||
|
wl.lock()
|
||||||
|
try {
|
||||||
|
return action()
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if(upgradeCount > 0) {
|
||||||
|
rl.lock(upgradeCount)
|
||||||
|
}
|
||||||
|
wl.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline private fun ReadLock.lock(readCount: Int) {
|
||||||
|
if(readCount > 0) {
|
||||||
|
for(j in 1..readCount) {
|
||||||
|
lock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline private fun ReadLock.unlock(readCount: Int) {
|
||||||
|
if(readCount > 0) {
|
||||||
|
for(j in 1..readCount) {
|
||||||
|
unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user