Remove locking in mailbox executor service

This commit is contained in:
DBotThePony 2024-02-04 20:20:03 +07:00
parent a1f7eaeee8
commit abf91f445e
Signed by: DBot
GPG Key ID: DCC23B5715498507
2 changed files with 52 additions and 53 deletions

View File

@ -4,7 +4,7 @@ kotlin.code.style=official
specifyKotlinAsDependency=false specifyKotlinAsDependency=false
projectGroup=ru.dbotthepony.kommons projectGroup=ru.dbotthepony.kommons
projectVersion=1.7.7 projectVersion=1.7.8
guavaDepVersion=33.0.0 guavaDepVersion=33.0.0
gsonDepVersion=2.8.9 gsonDepVersion=2.8.9

View File

@ -51,7 +51,6 @@ class MailboxExecutorService(thread: Thread = Thread.currentThread()) : Schedule
private val timers = LinkedList<Timer<*>>() private val timers = LinkedList<Timer<*>>()
private val repeatableTimers = LinkedList<RepeatableTimer>() private val repeatableTimers = LinkedList<RepeatableTimer>()
private val executionLock = ReentrantLock()
@Volatile @Volatile
private var isShutdown = false private var isShutdown = false
@ -138,60 +137,61 @@ class MailboxExecutorService(thread: Thread = Thread.currentThread()) : Schedule
if (!isTerminated) { if (!isTerminated) {
isTerminated = true isTerminated = true
executionLock.withLock { futureQueue.forEach {
timers.clear() it.cancel(false)
repeatableTimers.clear()
} }
futureQueue.clear()
timers.clear()
repeatableTimers.clear()
return return
} }
} }
executionLock.withLock { var next = futureQueue.poll()
var next = futureQueue.poll()
while (next != null) { while (next != null) {
if (isTerminated) return if (isTerminated) return
next.run() next.run()
Thread.interrupted()
next = futureQueue.poll()
}
while (!timers.isEmpty()) {
if (isTerminated) return
val first = timers.first
if (first.isCancelled) {
timers.removeFirst()
} else if (first.executeAt <= timeOrigin.nanos) {
first.run()
Thread.interrupted() Thread.interrupted()
next = futureQueue.poll() timers.removeFirst()
} else {
break
} }
}
while (!timers.isEmpty()) { if (repeatableTimers.isNotEmpty()) {
val executed = LinkedList<RepeatableTimer>()
while (repeatableTimers.isNotEmpty()) {
if (isTerminated) return if (isTerminated) return
val first = timers.first val first = repeatableTimers.first
if (first.isCancelled) { if (first.isDone) {
timers.removeFirst() repeatableTimers.removeFirst()
} else if (first.executeAt <= timeOrigin.nanos) { } else if (first.next <= timeOrigin.nanos) {
first.run() first.runAndReset()
Thread.interrupted() executed.add(first)
timers.removeFirst() repeatableTimers.removeFirst()
} else { } else {
break break
} }
} }
if (repeatableTimers.isNotEmpty()) { executed.forEach { repeatableTimers.enqueue(it) }
val executed = LinkedList<RepeatableTimer>()
while (repeatableTimers.isNotEmpty()) {
if (isTerminated) return
val first = repeatableTimers.first
if (first.isDone) {
repeatableTimers.removeFirst()
} else if (first.next <= timeOrigin.nanos) {
first.runAndReset()
executed.add(first)
repeatableTimers.removeFirst()
} else {
break
}
}
executed.forEach { repeatableTimers.enqueue(it) }
}
} }
} }
@ -210,27 +210,26 @@ class MailboxExecutorService(thread: Thread = Thread.currentThread()) : Schedule
isShutdown = true isShutdown = true
} }
override fun shutdownNow(): MutableList<Runnable> { override fun shutdownNow(): List<Runnable> {
if (isTerminated) return listOf()
isShutdown = true isShutdown = true
isTerminated = true isTerminated = true
val result = ArrayList<Runnable>() val result = ArrayList<Runnable>()
executionLock.withLock { futureQueue.forEach {
futureQueue.forEach { it.cancel(false)
it.cancel(false) result.add(it)
result.add(it)
}
futureQueue.clear()
timers.forEach { it.cancel(false) }
repeatableTimers.forEach { it.cancel(false) }
timers.clear()
repeatableTimers.clear()
} }
futureQueue.clear()
timers.forEach { it.cancel(false) }
repeatableTimers.forEach { it.cancel(false) }
timers.clear()
repeatableTimers.clear()
return result return result
} }