locks.nim 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module contains Nim's support for locks and condition vars.
  10. #[
  11. for js, for now we treat locks as noop's to avoid pushing `when defined(js)`
  12. in client code that uses locks.
  13. ]#
  14. when not compileOption("threads") and not defined(nimdoc):
  15. when false: # fix #12330
  16. {.error: "Locks requires --threads:on option.".}
  17. import std/private/syslocks
  18. type
  19. Lock* = SysLock ## Nim lock; whether this is re-entrant
  20. ## or not is unspecified!
  21. Cond* = SysCond ## Nim condition variable
  22. {.push stackTrace: off.}
  23. proc `$`*(lock: Lock): string =
  24. # workaround bug #14873
  25. result = "()"
  26. proc initLock*(lock: var Lock) {.inline.} =
  27. ## Initializes the given lock.
  28. when not defined(js):
  29. initSysLock(lock)
  30. proc deinitLock*(lock: var Lock) {.inline.} =
  31. ## Frees the resources associated with the lock.
  32. deinitSys(lock)
  33. proc tryAcquire*(lock: var Lock): bool {.inline.} =
  34. ## Tries to acquire the given lock. Returns `true` on success.
  35. result = tryAcquireSys(lock)
  36. proc acquire*(lock: var Lock) {.inline.} =
  37. ## Acquires the given lock.
  38. when not defined(js):
  39. acquireSys(lock)
  40. proc release*(lock: var Lock) {.inline.} =
  41. ## Releases the given lock.
  42. when not defined(js):
  43. releaseSys(lock)
  44. proc initCond*(cond: var Cond) {.inline.} =
  45. ## Initializes the given condition variable.
  46. initSysCond(cond)
  47. proc deinitCond*(cond: var Cond) {.inline.} =
  48. ## Frees the resources associated with the condition variable.
  49. deinitSysCond(cond)
  50. proc wait*(cond: var Cond, lock: var Lock) {.inline.} =
  51. ## Waits on the condition variable `cond`.
  52. waitSysCond(cond, lock)
  53. proc signal*(cond: var Cond) {.inline.} =
  54. ## Sends a signal to the condition variable `cond`.
  55. signalSysCond(cond)
  56. proc broadcast*(cond: var Cond) {.inline.} =
  57. ## Unblocks all threads currently blocked on the
  58. ## specified condition variable `cond`.
  59. broadcastSysCond(cond)
  60. template withLock*(a: Lock, body: untyped) =
  61. ## Acquires the given lock, executes the statements in body and
  62. ## releases the lock after the statements finish executing.
  63. acquire(a)
  64. {.locks: [a].}:
  65. try:
  66. body
  67. finally:
  68. release(a)
  69. {.pop.}