tisolated_lock.nim 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. discard """
  2. cmd: "nim $target --threads:on $options $file"
  3. action: "compile"
  4. """
  5. import std / [os, locks, atomics, isolation]
  6. type
  7. MyList {.acyclic.} = ref object
  8. data: string
  9. next: Isolated[MyList]
  10. template withMyLock*(a: Lock, body: untyped) =
  11. acquire(a)
  12. {.gcsafe.}:
  13. try:
  14. body
  15. finally:
  16. release(a)
  17. var head: Isolated[MyList]
  18. var headL: Lock
  19. var shouldStop: Atomic[bool]
  20. initLock headL
  21. proc send(x: sink string) =
  22. withMyLock headL:
  23. head = isolate MyList(data: x, next: move head)
  24. proc worker() {.thread.} =
  25. var workItem = MyList(nil)
  26. var echoed = 0
  27. while true:
  28. withMyLock headL:
  29. var h = extract head
  30. if h != nil:
  31. workItem = h
  32. # workitem is now isolated:
  33. head = move h.next
  34. else:
  35. workItem = nil
  36. # workItem is isolated, so we can access it outside
  37. # the lock:
  38. if workItem.isNil:
  39. if shouldStop.load:
  40. break
  41. else:
  42. # give producer time to breath:
  43. os.sleep 30
  44. else:
  45. if echoed < 100:
  46. echo workItem.data
  47. inc echoed
  48. var thr: Thread[void]
  49. createThread(thr, worker)
  50. send "abc"
  51. send "def"
  52. for i in 0 ..< 10_000:
  53. send "xzy"
  54. send "zzz"
  55. shouldStop.store true
  56. joinThread(thr)