7
|
1 package com.bartsent.simpleresizer.lib
|
|
2
|
9
|
3 import android.util.Log
|
7
|
4 import java.util.concurrent.Semaphore
|
|
5
|
|
6 /**
|
|
7 * A typed, buffered communications channel a'la C.A.R. Hoare's communicating sequential
|
|
8 * processes (CSP).
|
|
9 */
|
|
10 class Channel<T: Any>(capacity: Int) {
|
|
11 private val buffer = Array<Any?>(capacity) { null }
|
|
12 private var start = 0
|
|
13 private val wSem = Semaphore(capacity)
|
|
14 private val rSem = Semaphore(0)
|
|
15
|
|
16 /**
|
|
17 * Write a single item to this channel.
|
|
18 * @param item Item to write
|
|
19 */
|
|
20 fun write(item: T): Unit {
|
9
|
21 Log.d("Channel<${hashCode()}>", "write…")
|
7
|
22 wSem.acquire()
|
|
23 synchronized(this) {
|
|
24 buffer[(start + rSem.availablePermits()) % buffer.size] = item
|
|
25 rSem.release()
|
|
26 }
|
9
|
27 Log.d("Channel<${hashCode()}>", "write done")
|
7
|
28 }
|
|
29
|
|
30 /**
|
|
31 * Read a single item from this channel.
|
|
32 * @return The item read
|
|
33 */
|
|
34 fun read(): T {
|
9
|
35 Log.d("Channel<${hashCode()}>", "read…")
|
7
|
36 rSem.acquire()
|
|
37 synchronized(this) {
|
|
38 val ret = buffer[start]!! as T
|
|
39 buffer[start] = null // unref
|
|
40 start = (start + 1) % buffer.size
|
|
41 wSem.release()
|
9
|
42 Log.d("Channel<${hashCode()}>", "read done")
|
7
|
43 return ret
|
|
44 }
|
|
45 }
|
|
46 }
|