Skip to content

Commit

Permalink
Merge pull request #60 from elcritch/fix-channel-atomic
Browse files Browse the repository at this point in the history
fix decrement and free in channel
  • Loading branch information
Araq authored Feb 10, 2024
2 parents 2ce3d80 + f9e3ec4 commit 7919537
Showing 1 changed file with 14 additions and 12 deletions.
26 changes: 14 additions & 12 deletions threading/channels.nim
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ func getAtomicCounter(chan: ChannelRaw, order: Ordering = Relaxed): int {.inline
proc setAtomicCounter(chan: ChannelRaw, value: int, order: Ordering = Relaxed) {.inline.} =
chan.atomicCounter.store(value, order)

func decrIsZero(chan: ChannelRaw): bool {.inline.} =
if chan.atomicCounter.fetchSub(1, AcqRel) == 0:
result = true

func numItems(chan: ChannelRaw): int {.inline.} =
result = chan.getHead() - chan.getTail()
if result < 0:
Expand Down Expand Up @@ -261,22 +265,20 @@ type
Chan*[T] = object ## Typed channel
d: ChannelRaw

proc decr[T](c: Chan[T]) {.inline.} =
if c.d != nil:
# this `fetchSub` returns current val then subs
# so count == 0 means we're the last
if c.d.decrIsZero():
if c.d.buffer != nil:
freeChannel(c.d)

when defined(nimAllowNonVarDestructor):
proc `=destroy`*[T](c: Chan[T]) =
if c.d != nil:
if c.d.getAtomicCounter(Acquire) == 0:
if c.d.buffer != nil:
freeChannel(c.d)
else:
atomicDec(c.d.atomicCounter)
c.decr()
else:
proc `=destroy`*[T](c: var Chan[T]) =
if c.d != nil:
if c.d.getAtomicCounter(Acquire) == 0:
if c.d.buffer != nil:
freeChannel(c.d)
else:
atomicDec(c.d.atomicCounter)
c.decr()

proc `=copy`*[T](dest: var Chan[T], src: Chan[T]) =
## Shares `Channel` by reference counting.
Expand Down

0 comments on commit 7919537

Please sign in to comment.