From f2f0b3e25d976446e657cee7157591ce587624fd Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Thu, 5 Oct 2023 01:41:39 +0800 Subject: fixes #22711; Check atomicArc for atomic destroy race condition (#22788) fixes #22711 Per @elcritch's awesome solution --- lib/system/arc.nim | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/system/arc.nim b/lib/system/arc.nim index 0624bd4e3..b49a6a63b 100644 --- a/lib/system/arc.nim +++ b/lib/system/arc.nim @@ -202,15 +202,22 @@ proc nimDecRefIsLast(p: pointer): bool {.compilerRtl, inl.} = writeStackTrace() cfprintf(cstderr, "[DecRef] %p %ld\n", p, cell.count) - if cell.count == 0: - result = true - when traceCollector: - cprintf("[ABOUT TO DESTROY] %p\n", cell) + when defined(gcAtomicArc) and hasThreadSupport: + # `atomicDec` returns the new value + if atomicDec(cell.rc, rcIncrement) == -1: + result = true + when traceCollector: + cprintf("[ABOUT TO DESTROY] %p\n", cell) else: - decrement cell - # According to Lins it's correct to do nothing else here. - when traceCollector: - cprintf("[DECREF] %p\n", cell) + if cell.count == 0: + result = true + when traceCollector: + cprintf("[ABOUT TO DESTROY] %p\n", cell) + else: + decrement cell + # According to Lins it's correct to do nothing else here. + when traceCollector: + cprintf("[DECREF] %p\n", cell) proc GC_unref*[T](x: ref T) = ## New runtime only supports this operation for 'ref T'. -- cgit 1.4.1-2-gfad0