Minor optimizations of UndispatchedEventLoop
diff --git a/common/kotlinx-coroutines-core-common/src/Dispatched.kt b/common/kotlinx-coroutines-core-common/src/Dispatched.kt
index 6fc1870..34aacae 100644
--- a/common/kotlinx-coroutines-core-common/src/Dispatched.kt
+++ b/common/kotlinx-coroutines-core-common/src/Dispatched.kt
@@ -13,53 +13,53 @@
 
 @NativeThreadLocal
 internal object UndispatchedEventLoop {
-    data class State(
+    data class EventLoop(
         @JvmField var isActive: Boolean = false,
-        @JvmField val threadLocalQueue: ArrayQueue<Runnable> = ArrayQueue()
+        @JvmField val queue: ArrayQueue<Runnable> = ArrayQueue()
     )
 
     @JvmField
-    internal val state = CommonThreadLocal { State() }
+    internal val threadLocalEventLoop = CommonThreadLocal { EventLoop() }
 
     inline fun execute(continuation: DispatchedContinuation<*>, contState: Any?, mode: Int, block: () -> Unit) {
-        val state = state.get()
-        if (state.isActive) {
+        val eventLoop = threadLocalEventLoop.get()
+        if (eventLoop.isActive) {
             continuation._state = contState
             continuation.resumeMode = mode
-            state.threadLocalQueue.addLast(continuation)
+            eventLoop.queue.addLast(continuation)
             return
         }
 
-        runLoop(state, block)
+        runEventLoop(eventLoop, block)
     }
 
     fun resumeUndispatched(task: DispatchedTask<*>) {
-        val state = state.get()
-        if (state.isActive) {
-            state.threadLocalQueue.addLast(task)
+        val eventLoop = threadLocalEventLoop.get()
+        if (eventLoop.isActive) {
+            eventLoop.queue.addLast(task)
             return
         }
 
-        runLoop(state, { task.resume(task.delegate, MODE_UNDISPATCHED) })
+        runEventLoop(eventLoop, { task.resume(task.delegate, MODE_UNDISPATCHED) })
     }
 
-    inline fun runLoop(state: State, block: () -> Unit) {
+    inline fun runEventLoop(eventLoop: EventLoop, block: () -> Unit) {
         try {
-            state.isActive = true
+            eventLoop.isActive = true
             block()
-            while (!state.threadLocalQueue.isEmpty) {
-                val element = state.threadLocalQueue.removeFirst()
-                element.run()
+            while (true) {
+                val nextEvent = eventLoop.queue.removeFirstOrNull() ?: return
+                nextEvent.run()
             }
         } catch (e: Throwable) {
             /*
              * This exception doesn't happen normally, only if user either submitted throwing runnable
              * or if we have a bug in implementation. Anyway, reset state of the dispatcher to the initial.
              */
-            state.threadLocalQueue.clear()
+            eventLoop.queue.clear()
             throw DispatchException("Unexpected exception in undispatched event loop, clearing pending tasks", e)
         } finally {
-            state.isActive = false
+            eventLoop.isActive = false
         }
     }
 }
diff --git a/common/kotlinx-coroutines-core-common/src/internal/ArrayQueue.kt b/common/kotlinx-coroutines-core-common/src/internal/ArrayQueue.kt
index be38183..a6bf8f6 100644
--- a/common/kotlinx-coroutines-core-common/src/internal/ArrayQueue.kt
+++ b/common/kotlinx-coroutines-core-common/src/internal/ArrayQueue.kt
@@ -5,8 +5,6 @@
 package kotlinx.coroutines.internal
 
 internal class ArrayQueue<T : Any> {
-    public val isEmpty: Boolean get() = head == tail
-
     private var elements = arrayOfNulls<Any>(16)
     private var head = 0
     private var tail = 0
@@ -18,12 +16,12 @@
     }
 
     @Suppress("UNCHECKED_CAST")
-    public fun removeFirst(): T {
-        require(head != tail) { "Queue is empty" }
+    public fun removeFirstOrNull(): T? {
+        if (head == tail) return null
         val element = elements[head]
         elements[head] = null
         head = (head + 1) and elements.size - 1
-        return element!! as T
+        return element as T
     }
 
     public fun clear() {