All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.org.jetbrains.skiko.RendezvousBroadcastChannel.kt Maven / Gradle / Ivy

There is a newer version: 0.6.7
Show newest version
package org.jetbrains.skiko

import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume

/**
 * Behaves as Channel(Channel.RENDEZVOUS), but with ability to send value to all current consumers
 * (which await on `receive` method).
 */
internal class RendezvousBroadcastChannel {
    private val onRequest = Channel(Channel.CONFLATED)
    private val receivers = mutableListOf>()

    /**
     * Send value to all current consumers which await value on `receive` method, or await for the first one.
     *
     * Can't be called concurrently from multiple threads.
     */
    suspend fun sendAll(value: T) {
        onRequest.receive()
        val receiversCopy = maybeSynchronized(receivers) {
            mutableListOf>().apply {
                addAll(receivers)
                receivers.clear()
            }
        }
        for (receiver in receiversCopy) {
            receiver.resume(value)
        }
    }

    /**
     * Wait when the producer will send a value and return it.
     *
     * Can be called concurrently from multiple threads.
     */
    suspend fun receive(): T = suspendCancellableCoroutine { continuation ->
        maybeSynchronized(receivers) {
            receivers.add(continuation)
        }
        onRequest.trySend(Unit)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy