aboutsummaryrefslogtreecommitdiff
path: root/core/sync
diff options
context:
space:
mode:
authorFeoramund <161657516+Feoramund@users.noreply.github.com>2024-09-09 14:42:50 -0400
committerFeoramund <161657516+Feoramund@users.noreply.github.com>2024-09-10 14:52:20 -0400
commit026aef69e3a42021c5d9666737c7401dc75dc89a (patch)
tree2dc2d0b0e7d796ff074c2cf4b07dc9b5aa1a4f8d /core/sync
parent73f5ab473c4129ae209838d7967286684ac3f462 (diff)
Fix deadlock on sending to full, buffered, closed `Chan`
This will also keep messages from being sent to closed, buffered channels in general.
Diffstat (limited to 'core/sync')
-rw-r--r--core/sync/chan/chan.odin7
1 files changed, 6 insertions, 1 deletions
diff --git a/core/sync/chan/chan.odin b/core/sync/chan/chan.odin
index aca08d82e..cb299f23f 100644
--- a/core/sync/chan/chan.odin
+++ b/core/sync/chan/chan.odin
@@ -164,12 +164,17 @@ send_raw :: proc "contextless" (c: ^Raw_Chan, msg_in: rawptr) -> (ok: bool) {
}
if c.queue != nil { // buffered
sync.guard(&c.mutex)
- for c.queue.len == c.queue.cap {
+ for !sync.atomic_load(&c.closed) &&
+ c.queue.len == c.queue.cap {
sync.atomic_add(&c.w_waiting, 1)
sync.wait(&c.w_cond, &c.mutex)
sync.atomic_sub(&c.w_waiting, 1)
}
+ if sync.atomic_load(&c.closed) {
+ return false
+ }
+
ok = raw_queue_push(c.queue, msg_in)
if sync.atomic_load(&c.r_waiting) > 0 {
sync.signal(&c.r_cond)