view app/src/main/java/com/bartsent/simpleresizer/lib/Channel.kt @ 9:884092efe31a concur

Gets gratuitously killed. WTF?
author David Barts <n5jrn@me.com>
date Wed, 17 Feb 2021 13:20:25 -0800
parents 9374d044a132
children
line wrap: on
line source

package com.bartsent.simpleresizer.lib

import android.util.Log
import java.util.concurrent.Semaphore

/**
 * A typed, buffered communications channel a'la C.A.R. Hoare's communicating sequential
 * processes (CSP).
 */
class Channel<T: Any>(capacity: Int) {
    private val buffer = Array<Any?>(capacity) { null }
    private var start = 0
    private val wSem = Semaphore(capacity)
    private val rSem = Semaphore(0)

    /**
     * Write a single item to this channel.
     * @param item      Item to write
     */
    fun write(item: T): Unit {
        Log.d("Channel<${hashCode()}>", "write…")
        wSem.acquire()
        synchronized(this) {
            buffer[(start + rSem.availablePermits()) % buffer.size] = item
            rSem.release()
        }
        Log.d("Channel<${hashCode()}>", "write done")
    }

    /**
     * Read a single item from this channel.
     * @return          The item read
     */
    fun read(): T {
        Log.d("Channel<${hashCode()}>", "read…")
        rSem.acquire()
        synchronized(this) {
            val ret = buffer[start]!! as T
            buffer[start] = null // unref
            start = (start + 1) % buffer.size
            wSem.release()
            Log.d("Channel<${hashCode()}>", "read done")
            return ret
        }
    }
}