Make mailbox be lightweight as possible

This commit is contained in:
DBotThePony 2023-10-26 00:34:06 +07:00
parent 792e0c6ff6
commit f0791a47b7
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -38,10 +38,7 @@ private fun <E : Comparable<E>> LinkedList<E>.enqueue(value: E) {
}
class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : ScheduledExecutorService {
private val executeQueue = ConcurrentLinkedQueue<Runnable>()
private val futureQueue = ConcurrentLinkedQueue<FutureTask<*>>()
private val timerBacklog = ConcurrentLinkedQueue<Timer<*>>()
private val repeatableTimersBacklog = ConcurrentLinkedQueue<RepeatableTimer>()
private val timers = LinkedList<Timer<*>>()
private val repeatableTimers = LinkedList<RepeatableTimer>()
@ -116,51 +113,13 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche
}
executionLock.withLock {
var next = executeQueue.poll()
var next = futureQueue.poll()
while (next != null) {
if (isTerminated) return
next.run()
next = executeQueue.poll()
}
var next2 = futureQueue.poll()
while (next2 != null) {
if (isTerminated) return
next2.run()
Thread.interrupted()
next2 = futureQueue.poll()
}
var next3 = timerBacklog.poll()
while (next3 != null) {
if (isTerminated) return
if (next3.isCancelled) {
// do nothing
} else if (next3.executeAt <= timeOrigin.nanos) {
next3.run()
Thread.interrupted()
} else {
timers.enqueue(next3)
}
next3 = timerBacklog.poll()
}
var next4 = repeatableTimersBacklog.poll()
while (next4 != null) {
if (isTerminated) return
if (next4.isCancelled) {
// do nothing
} else {
repeatableTimers.enqueue(next4)
}
next4 = repeatableTimersBacklog.poll()
next = futureQueue.poll()
}
while (!timers.isEmpty()) {
@ -207,7 +166,7 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche
if (isSameThread()) {
command.run()
} else {
executeQueue.add(command)
futureQueue.add(FutureTask(command, Unit))
LockSupport.unpark(thread)
}
}
@ -223,9 +182,6 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche
val result = ArrayList<Runnable>()
executionLock.withLock {
executeQueue.forEach { result.add(it) }
executeQueue.clear()
futureQueue.forEach {
it.cancel(false)
result.add(it)
@ -347,7 +303,16 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche
} else if (isSameThread()) {
timers.enqueue(timer)
} else {
timerBacklog.add(timer)
execute {
if (timer.isCancelled) {
// do nothing
} else if (timer.executeAt <= timeOrigin.nanos) {
timer.run()
Thread.interrupted()
} else {
timers.enqueue(timer)
}
}
}
return timer
@ -364,7 +329,16 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche
} else if (isSameThread()) {
timers.enqueue(timer)
} else {
timerBacklog.add(timer)
execute {
if (timer.isCancelled) {
// do nothing
} else if (timer.executeAt <= timeOrigin.nanos) {
timer.run()
Thread.interrupted()
} else {
timers.enqueue(timer)
}
}
}
return timer
@ -381,7 +355,16 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche
return RepeatableTimer(
command,
timeOrigin.nanos + TimeUnit.NANOSECONDS.convert(initialDelay, unit),
TimeUnit.NANOSECONDS.convert(period, unit), true).also { repeatableTimersBacklog.add(it) }
TimeUnit.NANOSECONDS.convert(period, unit), true)
.also {
execute {
if (it.isCancelled) {
// do nothing
} else {
repeatableTimers.enqueue(it)
}
}
}
}
override fun scheduleWithFixedDelay(
@ -395,6 +378,15 @@ class MailboxExecutorService(val thread: Thread = Thread.currentThread()) : Sche
return RepeatableTimer(
command,
timeOrigin.nanos + TimeUnit.NANOSECONDS.convert(initialDelay, unit),
TimeUnit.NANOSECONDS.convert(delay, unit), false).also { repeatableTimersBacklog.add(it) }
TimeUnit.NANOSECONDS.convert(delay, unit), false)
.also {
execute {
if (it.isCancelled) {
// do nothing
} else {
repeatableTimers.enqueue(it)
}
}
}
}
}