aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/sync/channel_select_3_test.v
diff options
context:
space:
mode:
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.v122
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
+}