diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-10-05 01:41:39 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-04 19:41:39 +0200 |
commit | f2f0b3e25d976446e657cee7157591ce587624fd (patch) | |
tree | 22145efb9711e4f6081ff3ff3495c3f21d6d1190 | |
parent | f4a623dadf1a5ba287dbb55893ab70d1d6638c3f (diff) | |
download | Nim-f2f0b3e25d976446e657cee7157591ce587624fd.tar.gz |
fixes #22711; Check atomicArc for atomic destroy race condition (#22788)
fixes #22711 Per @elcritch's awesome solution
-rw-r--r-- | lib/system/arc.nim | 23 |
1 files 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'. |