117 lines
1.6 KiB
V
117 lines
1.6 KiB
V
import time
|
|
import sync
|
|
|
|
struct St {
|
|
a int
|
|
}
|
|
|
|
fn getint() int {
|
|
return 8
|
|
}
|
|
|
|
fn f1(ch1 chan int, ch2 chan St, ch3 chan int, ch4 chan int, ch5 chan int, sem sync.Semaphore) {
|
|
mut a := 5
|
|
select {
|
|
a = <-ch3 {
|
|
a = 0
|
|
}
|
|
b := <-ch2 {
|
|
a = b.a
|
|
}
|
|
ch3 <- 5 {
|
|
a = 1
|
|
}
|
|
ch2 <- St{a: 37} {
|
|
a = 2
|
|
}
|
|
ch4 <- (6 + 7 * 9) {
|
|
a = 8
|
|
}
|
|
ch5 <- getint() {
|
|
a = 9
|
|
}
|
|
> 300 * time.millisecond {
|
|
a = 3
|
|
}
|
|
}
|
|
assert a == 3
|
|
sem.post()
|
|
}
|
|
|
|
fn f2(ch1 chan St, ch2 chan int, sem sync.Semaphore) {
|
|
mut r := 23
|
|
for i in 0 .. 2 {
|
|
select {
|
|
b := <-ch1 {
|
|
r = b.a
|
|
}
|
|
ch2 <- r {
|
|
r = 17
|
|
}
|
|
}
|
|
if i == 0 {
|
|
assert r == 17
|
|
} else {
|
|
assert r == 13
|
|
}
|
|
}
|
|
sem.post()
|
|
}
|
|
|
|
fn test_select_blocks() {
|
|
ch1 := chan int{cap: 1}
|
|
ch2 := chan St{}
|
|
ch3 := chan int{}
|
|
ch4 := chan int{}
|
|
ch5 := chan int{}
|
|
sem := sync.new_semaphore()
|
|
mut r := false
|
|
t := select {
|
|
b := <- ch1 {
|
|
println(b)
|
|
}
|
|
else {
|
|
// no channel ready
|
|
r = true
|
|
}
|
|
}
|
|
assert r == true
|
|
assert t == true
|
|
go f2(ch2, ch3, sem)
|
|
n := <-ch3
|
|
assert n == 23
|
|
ch2 <- St{a: 13}
|
|
sem.wait()
|
|
stopwatch := time.new_stopwatch({})
|
|
go f1(ch1, ch2, ch3, ch4, ch5, sem)
|
|
sem.wait()
|
|
elapsed_ms := f64(stopwatch.elapsed()) / time.millisecond
|
|
assert elapsed_ms >= 295.0
|
|
|
|
ch1.close()
|
|
ch2.close()
|
|
mut h := 7
|
|
mut is_open := true
|
|
if select {
|
|
b := <- ch2 {
|
|
h = 0
|
|
}
|
|
ch1 <- h {
|
|
h = 1
|
|
}
|
|
else {
|
|
h = 2
|
|
}
|
|
} {
|
|
panic('channel is still open')
|
|
} else {
|
|
is_open = false
|
|
}
|
|
// no branch should have run
|
|
assert h == 7
|
|
// since all channels are closed `select` should return `false`
|
|
assert is_open == false
|
|
}
|
|
|
|
|