locks.nim 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. const insideRLocksModule = false
  18. include "system/syslocks"
  19. type
  20. Lock* = SysLock ## Nim lock; whether this is re-entrant
  21. ## or not is unspecified!
  22. Cond* = SysCond ## Nim condition variable
  23. {.push stackTrace: off.}
  24. proc `$`*(lock: Lock): string =
  25. # workaround bug #14873
  26. result = "()"
  27. proc initLock*(lock: var Lock) {.inline.} =
  28. ## Initializes the given lock.
  29. when not defined(js):
  30. initSysLock(lock)
  31. proc deinitLock*(lock: var Lock) {.inline.} =
  32. ## Frees the resources associated with the lock.
  33. deinitSys(lock)
  34. proc tryAcquire*(lock: var Lock): bool {.inline.} =
  35. ## Tries to acquire the given lock. Returns `true` on success.
  36. result = tryAcquireSys(lock)
  37. proc acquire*(lock: var Lock) {.inline.} =
  38. ## Acquires the given lock.
  39. when not defined(js):
  40. acquireSys(lock)
  41. proc release*(lock: var Lock) {.inline.} =
  42. ## Releases the given lock.
  43. when not defined(js):
  44. releaseSys(lock)
  45. proc initCond*(cond: var Cond) {.inline.} =
  46. ## Initializes the given condition variable.
  47. initSysCond(cond)
  48. proc deinitCond*(cond: var Cond) {.inline.} =
  49. ## Frees the resources associated with the condition variable.
  50. deinitSysCond(cond)
  51. proc wait*(cond: var Cond, lock: var Lock) {.inline.} =
  52. ## Waits on the condition variable `cond`.
  53. waitSysCond(cond, lock)
  54. proc signal*(cond: var Cond) {.inline.} =
  55. ## Sends a signal to the condition variable `cond`.
  56. signalSysCond(cond)
  57. proc broadcast*(cond: var Cond) {.inline.} =
  58. ## Unblocks all threads currently blocked on the
  59. ## specified condition variable `cond`.
  60. broadcastSysCond(cond)
  61. template withLock*(a: Lock, body: untyped) =
  62. ## Acquires the given lock, executes the statements in body and
  63. ## releases the lock after the statements finish executing.
  64. acquire(a)
  65. {.locks: [a].}:
  66. try:
  67. body
  68. finally:
  69. release(a)
  70. {.pop.}