Blockable event loop without locking
This commit is contained in:
parent
a66de1133a
commit
100afadd5c
@ -9,6 +9,7 @@ import org.apache.logging.log4j.LogManager
|
|||||||
import java.util.PriorityQueue
|
import java.util.PriorityQueue
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
import java.util.concurrent.Delayed
|
import java.util.concurrent.Delayed
|
||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
import java.util.concurrent.FutureTask
|
import java.util.concurrent.FutureTask
|
||||||
@ -81,13 +82,13 @@ open class BlockableEventLoop(name: String) : Thread(name), ScheduledExecutorSer
|
|||||||
|
|
||||||
private class TaskPair<T>(val future: CompletableFuture<T>, var supplier: Callable<T>?)
|
private class TaskPair<T>(val future: CompletableFuture<T>, var supplier: Callable<T>?)
|
||||||
|
|
||||||
private val eventQueue = LinkedBlockingQueue<TaskPair<*>>()
|
private val eventQueue = ConcurrentLinkedQueue<TaskPair<*>>()
|
||||||
private val scheduledQueue = PriorityQueue<ScheduledTask<*>>()
|
private val scheduledQueue = PriorityQueue<ScheduledTask<*>>()
|
||||||
val coroutines = asCoroutineDispatcher()
|
val coroutines = asCoroutineDispatcher()
|
||||||
val scope = CoroutineScope(coroutines + SupervisorJob())
|
val scope = CoroutineScope(coroutines + SupervisorJob())
|
||||||
|
|
||||||
private fun nextDeadline(): Long {
|
private fun nextDeadline(): Long {
|
||||||
if (isShutdown)
|
if (isShutdown || eventQueue.isNotEmpty())
|
||||||
return 0L
|
return 0L
|
||||||
|
|
||||||
val poll = scheduledQueue.peek()
|
val poll = scheduledQueue.peek()
|
||||||
@ -105,7 +106,7 @@ open class BlockableEventLoop(name: String) : Thread(name), ScheduledExecutorSer
|
|||||||
|
|
||||||
private fun eventLoopIteration(): Boolean {
|
private fun eventLoopIteration(): Boolean {
|
||||||
var executedAnything = false
|
var executedAnything = false
|
||||||
val next = eventQueue.poll(nextDeadline(), TimeUnit.NANOSECONDS)
|
val next = eventQueue.poll()
|
||||||
|
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
executedAnything = true
|
executedAnything = true
|
||||||
@ -152,6 +153,7 @@ open class BlockableEventLoop(name: String) : Thread(name), ScheduledExecutorSer
|
|||||||
|
|
||||||
final override fun run() {
|
final override fun run() {
|
||||||
while (isRunning) {
|
while (isRunning) {
|
||||||
|
LockSupport.parkNanos(nextDeadline())
|
||||||
eventLoopIteration()
|
eventLoopIteration()
|
||||||
|
|
||||||
if (isShutdown && isRunning) {
|
if (isShutdown && isRunning) {
|
||||||
@ -180,6 +182,7 @@ open class BlockableEventLoop(name: String) : Thread(name), ScheduledExecutorSer
|
|||||||
}
|
}
|
||||||
|
|
||||||
eventQueue.add(pair)
|
eventQueue.add(pair)
|
||||||
|
LockSupport.unpark(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,6 +206,7 @@ open class BlockableEventLoop(name: String) : Thread(name), ScheduledExecutorSer
|
|||||||
}
|
}
|
||||||
|
|
||||||
eventQueue.add(pair)
|
eventQueue.add(pair)
|
||||||
|
LockSupport.unpark(this)
|
||||||
return future
|
return future
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,6 +244,7 @@ open class BlockableEventLoop(name: String) : Thread(name), ScheduledExecutorSer
|
|||||||
}
|
}
|
||||||
|
|
||||||
eventQueue.add(pair)
|
eventQueue.add(pair)
|
||||||
|
LockSupport.unpark(this)
|
||||||
return future
|
return future
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,6 +270,7 @@ open class BlockableEventLoop(name: String) : Thread(name), ScheduledExecutorSer
|
|||||||
}
|
}
|
||||||
|
|
||||||
eventQueue.add(pair)
|
eventQueue.add(pair)
|
||||||
|
LockSupport.unpark(this)
|
||||||
return future
|
return future
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -321,7 +327,7 @@ open class BlockableEventLoop(name: String) : Thread(name), ScheduledExecutorSer
|
|||||||
performShutdown()
|
performShutdown()
|
||||||
} else {
|
} else {
|
||||||
// wake up thread
|
// wake up thread
|
||||||
eventQueue.add(TaskPair(CompletableFuture()) { })
|
LockSupport.unpark(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -359,7 +365,8 @@ open class BlockableEventLoop(name: String) : Thread(name), ScheduledExecutorSer
|
|||||||
scope.cancel(CancellationException("EventLoop shut down"))
|
scope.cancel(CancellationException("EventLoop shut down"))
|
||||||
performShutdown()
|
performShutdown()
|
||||||
} else {
|
} else {
|
||||||
eventQueue.add(TaskPair(CompletableFuture()) { })
|
// wake up thread
|
||||||
|
LockSupport.unpark(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user