import sync import time struct St { mut: a int } fn (shared x St) f(shared z St) { for _ in 0 .. reads_per_thread { rlock x { // other instances may read at the same time time.sleep(time.millisecond) assert x.a == 7 || x.a == 5 } } lock z { z.a-- } } fn g() shared St { shared x := St{a: 12 } return x } fn h() ?shared St { return error('no value') } fn k() { shared x := g() shared y := h() or { shared f := St{} f } shared z := h()? shared p := v v := rlock z { z.a } rlock x; lock y, z; rlock p { z.a = x.a + y.a } println(v) } const ( reads_per_thread = 30 read_threads = 10 writes = 5 ) fn test_shared_lock() { // object with separate read/write lock shared x := &St { a: 5 } shared z := &St{ a: read_threads } for _ in 0.. read_threads { spawn x.f(shared z) } for i in 0..writes { lock x { // wait for ongoing reads to finish, don't start new ones x.a = 17 // this value should never be read time.sleep(50* time.millisecond) x.a = if (i & 1) == 0 { 7 } else { 5 } } // now new reads are possible again time.sleep(20*time.millisecond) } // wait until all read threads are finished for finished:=false;; { mut rr := 0 rlock z { rr = z.a finished = z.a == 0 } if finished { break } time.sleep(100*time.millisecond) } }