exitprocs.nim 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2020 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. import locks
  10. type
  11. FunKind = enum kClosure, kNoconv # extend as needed
  12. Fun = object
  13. case kind: FunKind
  14. of kClosure: fun1: proc () {.closure.}
  15. of kNoconv: fun2: proc () {.noconv.}
  16. var
  17. gFunsLock: Lock
  18. gFuns: seq[Fun]
  19. initLock(gFunsLock)
  20. when defined(js):
  21. proc addAtExit(quitProc: proc() {.noconv.}) =
  22. when defined(nodejs):
  23. asm """
  24. process.on('exit', `quitProc`);
  25. """
  26. elif defined(js):
  27. asm """
  28. window.onbeforeunload = `quitProc`;
  29. """
  30. else:
  31. proc addAtExit(quitProc: proc() {.noconv.}) {.
  32. importc: "atexit", header: "<stdlib.h>".}
  33. proc callClosures() {.noconv.} =
  34. withLock gFunsLock:
  35. for i in countdown(gFuns.len-1, 0):
  36. let fun = gFuns[i]
  37. case fun.kind
  38. of kClosure: fun.fun1()
  39. of kNoconv: fun.fun2()
  40. template fun() =
  41. if gFuns.len == 0:
  42. addAtExit(callClosures)
  43. proc addExitProc*(cl: proc () {.closure.}) =
  44. ## Adds/registers a quit procedure. Each call to `addExitProc` registers
  45. ## another quit procedure. They are executed on a last-in, first-out basis.
  46. # Support for `addExitProc` is done by Ansi C's facilities here.
  47. # In case of an unhandled exception the exit handlers should
  48. # not be called explicitly! The user may decide to do this manually though.
  49. withLock gFunsLock:
  50. fun()
  51. gFuns.add Fun(kind: kClosure, fun1: cl)
  52. proc addExitProc*(cl: proc() {.noconv.}) =
  53. ## overload for `noconv` procs.
  54. withLock gFunsLock:
  55. fun()
  56. gFuns.add Fun(kind: kNoconv, fun2: cl)
  57. when not defined(nimscript):
  58. proc getProgramResult*(): int =
  59. when defined(js) and defined(nodejs):
  60. asm """
  61. `result` = process.exitCode;
  62. """
  63. elif not defined(js):
  64. result = programResult
  65. else:
  66. doAssert false
  67. proc setProgramResult*(a: int) =
  68. # pending https://github.com/nim-lang/Nim/issues/14674
  69. when defined(js) and defined(nodejs):
  70. asm """
  71. process.exitCode = `a`;
  72. """
  73. elif not defined(js):
  74. programResult = a
  75. else:
  76. doAssert false