1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- discard """
- cmd: "nim c --threads:on --gc:arc $file"
- action: compile
- """
- # bug #17893
- type
- SharedPtr*[T] = object
- val: ptr tuple[value: T, atomicCounter: int]
- proc `=destroy`*[T](p: var SharedPtr[T]) =
- mixin `=destroy`
- if p.val != nil:
- if atomicLoadN(addr p.val[].atomicCounter, AtomicConsume) == 0:
- `=destroy`(p.val[])
- deallocShared(p.val)
- else:
- discard atomicDec(p.val[].atomicCounter)
- proc `=copy`*[T](dest: var SharedPtr[T], src: SharedPtr[T]) =
- if src.val != nil:
- discard atomicInc(src.val[].atomicCounter)
- if dest.val != nil:
- `=destroy`(dest)
- dest.val = src.val
- proc newSharedPtr*[T](val: sink T): SharedPtr[T] {.nodestroy.} =
- result.val = cast[typeof(result.val)](allocShared(sizeof(result.val[])))
- result.val.atomicCounter = 0
- result.val.value = val
- proc isNil*[T](p: SharedPtr[T]): bool {.inline.} =
- p.val == nil
- proc `[]`*[T](p: SharedPtr[T]): var T {.inline.} =
- when compileOption("boundChecks"):
- doAssert(p.val != nil, "deferencing nil shared pointer")
- result = p.val.value
- type
- Sender*[T] = object
- queue: SharedPtr[seq[T]]
- proc newSender*[T](queue: sink SharedPtr[seq[T]]): Sender[T] =
- result = Sender[T](queue: queue)
- proc send*[T](self: Sender[T]; t: sink T) =
- self.queue[].add t
- proc newChannel*(): Sender[int] =
- let queue = newSharedPtr(newSeq[int]())
- result = newSender(queue)
- var
- p: Thread[Sender[int]]
- proc threadFn(tx: Sender[int]) =
- send tx, 0
- proc multiThreadedChannel =
- let tx = newChannel()
- createThread(p, threadFn, tx)
- joinThread(p)
- multiThreadedChannel()
|