diff options
Diffstat (limited to 'v_windows/v/vlib/sync/channel_select_3_test.v')
-rw-r--r-- | v_windows/v/vlib/sync/channel_select_3_test.v | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/v_windows/v/vlib/sync/channel_select_3_test.v b/v_windows/v/vlib/sync/channel_select_3_test.v new file mode 100644 index 0000000..fdf6096 --- /dev/null +++ b/v_windows/v/vlib/sync/channel_select_3_test.v @@ -0,0 +1,122 @@ +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, mut 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, mut 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{} + mut 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, mut sem) + n := <-ch3 + assert n == 23 + ch2 <- St{ + a: 13 + } + sem.wait() + stopwatch := time.new_stopwatch() + go f1(ch1, ch2, ch3, ch4, ch5, mut sem) + sem.wait() + elapsed_ms := f64(stopwatch.elapsed()) / time.millisecond + // https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/high-resolution-timers + // > For example, for Windows running on an x86 processor, the default interval between + // > system clock ticks is typically about 15 milliseconds, and the minimum interval + // > between system clock ticks is about 1 millisecond. + assert elapsed_ms >= 280.0 // 300 - (15ms + 5ms just in case) + + ch1.close() + ch2.close() + mut h := 7 + mut is_open := true + if select { + _ := <-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 +} |