Attempt to select SelectInstance in onReceiveOrClosed before starting a coroutine to avoid double resume

Fixed #1584
diff --git a/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt b/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt
index 6947b76..18a64c8 100644
--- a/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt
+++ b/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt
@@ -747,7 +747,7 @@
                         }
                     }
                     else -> {
-                        // selected successfully
+                        // selected successfully, pollSelectInternal is responsible for the select
                         block.startCoroutineUnintercepted(pollResult as E, select.completion)
                         return
                     }
@@ -776,10 +776,12 @@
                     pollResult === POLL_FAILED -> {} // retry
                     pollResult === RETRY_ATOMIC -> {} // retry
                     pollResult is Closed<*> -> {
-                        block.startCoroutineUnintercepted(ValueOrClosed.closed(pollResult.closeCause), select.completion)
+                        if (select.trySelect())
+                            block.startCoroutineUnintercepted(ValueOrClosed.closed(pollResult.closeCause), select.completion)
+                        return
                     }
                     else -> {
-                        // selected successfully
+                        // selected successfully, pollSelectInternal is responsible for the select
                         block.startCoroutineUnintercepted(ValueOrClosed.value(pollResult as E), select.completion)
                         return
                     }
diff --git a/kotlinx-coroutines-core/common/test/selects/SelectArrayChannelTest.kt b/kotlinx-coroutines-core/common/test/selects/SelectArrayChannelTest.kt
index c9747c6..a4f8c3b 100644
--- a/kotlinx-coroutines-core/common/test/selects/SelectArrayChannelTest.kt
+++ b/kotlinx-coroutines-core/common/test/selects/SelectArrayChannelTest.kt
@@ -388,4 +388,35 @@
         if (!trySelect()) return
         block.startCoroutineUnintercepted(this)
     }
+
+    @Test
+    fun testSelectReceiveOrClosedForClosedChannel() = runTest {
+        val channel = Channel<Int>(1)
+        channel.close()
+        expect(1)
+        select<Unit> {
+            expect(2)
+            channel.onReceiveOrClosed {
+                assertTrue(it.isClosed)
+                assertNull(it.closeCause)
+                finish(3)
+            }
+        }
+    }
+
+    @Test
+    fun testSelectReceiveOrClosedForClosedChannelWithValue() = runTest {
+        val channel = Channel<Int>(1)
+        channel.send(42)
+        channel.close()
+        expect(1)
+        select<Unit> {
+            expect(2)
+            channel.onReceiveOrClosed {
+                assertFalse(it.isClosed)
+                assertEquals(42, it.value)
+                finish(3)
+            }
+        }
+    }
 }
diff --git a/kotlinx-coroutines-core/common/test/selects/SelectRendezvousChannelTest.kt b/kotlinx-coroutines-core/common/test/selects/SelectRendezvousChannelTest.kt
index e84514e..2027630 100644
--- a/kotlinx-coroutines-core/common/test/selects/SelectRendezvousChannelTest.kt
+++ b/kotlinx-coroutines-core/common/test/selects/SelectRendezvousChannelTest.kt
@@ -348,6 +348,21 @@
     }
 
     @Test
+    fun testSelectReceiveOrClosedForClosedChannel() = runTest {
+        val channel = Channel<Unit>()
+        channel.close()
+        expect(1)
+        select<Unit> {
+            expect(2)
+            channel.onReceiveOrClosed {
+                assertTrue(it.isClosed)
+                assertNull(it.closeCause)
+                finish(3)
+            }
+        }
+    }
+
+    @Test
     fun testSelectReceiveOrClosed() = runTest {
         val channel = Channel<Int>(Channel.RENDEZVOUS)
         val iterations = 10