sync: fix `chan.close()` while a sending thread is waiting (#9654)
parent
062ee4356d
commit
bf9fe659a9
|
@ -1,4 +1,4 @@
|
||||||
import sync
|
import time
|
||||||
|
|
||||||
fn do_rec(ch chan int, resch chan i64) {
|
fn do_rec(ch chan int, resch chan i64) {
|
||||||
mut sum := i64(0)
|
mut sum := i64(0)
|
||||||
|
@ -71,3 +71,38 @@ fn test_channel_close_unbuffered() {
|
||||||
sum += <-resch
|
sum += <-resch
|
||||||
assert sum == i64(8000) * (8000 - 1) / 2
|
assert sum == i64(8000) * (8000 - 1) / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_channel_send_close_buffered() {
|
||||||
|
ch := chan int{cap: 1}
|
||||||
|
t := go fn (ch chan int) {
|
||||||
|
ch <- 31
|
||||||
|
mut x := 45
|
||||||
|
ch <- 17 or {
|
||||||
|
x = -133
|
||||||
|
}
|
||||||
|
assert x == -133
|
||||||
|
}(ch)
|
||||||
|
time.sleep(100 * time.millisecond)
|
||||||
|
ch.close()
|
||||||
|
mut r := <-ch
|
||||||
|
r = <-ch or { 23 }
|
||||||
|
assert r == 23
|
||||||
|
t.wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_channel_send_close_unbuffered() {
|
||||||
|
time.sleep(1 * time.second)
|
||||||
|
ch := chan int{}
|
||||||
|
t := go fn (ch chan int) {
|
||||||
|
mut x := 31
|
||||||
|
ch <- 177 or {
|
||||||
|
x = -71
|
||||||
|
}
|
||||||
|
assert x == -71
|
||||||
|
}(ch)
|
||||||
|
time.sleep(100 * time.millisecond)
|
||||||
|
ch.close()
|
||||||
|
r := <-ch or { 238 }
|
||||||
|
assert r == 238
|
||||||
|
t.wait()
|
||||||
|
}
|
||||||
|
|
|
@ -165,6 +165,9 @@ pub fn (mut ch Channel) close() {
|
||||||
}
|
}
|
||||||
C.atomic_store_u16(&ch.write_sub_mtx, u16(0))
|
C.atomic_store_u16(&ch.write_sub_mtx, u16(0))
|
||||||
ch.writesem.post()
|
ch.writesem.post()
|
||||||
|
if ch.cap == 0 {
|
||||||
|
C.atomic_store_ptr(&ch.read_adr, voidptr(0))
|
||||||
|
}
|
||||||
ch.writesem_im.post()
|
ch.writesem_im.post()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue