signals.nim 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2022 Emery Hemingway
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## See `Genode Foundations - Asynchronous notifications <https://genode.org/documentation/genode-foundations/21.05/architecture/Inter-component_communication.html#Asynchronous_notifications>`
  10. ## for a description of Genode signals.
  11. when not defined(genode) or defined(nimdoc):
  12. {.error: "Genode only module".}
  13. import ./entrypoints, ./constructibles
  14. export ep # Entrypoint accessor on GenodeEnv
  15. type
  16. SignalContextCapability* {.
  17. importcpp: "Genode::Signal_context_capability",
  18. header: "<base/signal.h>", pure.} = object
  19. ## Capability to an asynchronous signal context.
  20. proc isValid*(cap: SignalContextCapability): bool {.importcpp: "#.valid()".}
  21. ## Call the Genode core to check if this `SignalContextCapability` is valid.
  22. # TODO: RpcEffect
  23. type
  24. HandlerProc = proc () {.closure, gcsafe.}
  25. SignalHandlerBase {.
  26. importcpp: "Nim::SignalHandler",
  27. header: "genode_cpp/signals.h",
  28. pure.} = object
  29. SignalHandlerCpp = Constructible[SignalHandlerBase]
  30. SignalHandlerObj = object
  31. cpp: SignalHandlerCpp
  32. cb: HandlerProc
  33. ## Signal handling procedure called during dispatch.
  34. SignalHandler* = ref SignalHandlerObj
  35. ## Nim object enclosing a Genode signal handler.
  36. proc construct(cpp: SignalHandlerCpp; ep: Entrypoint; sh: SignalHandler) {.importcpp.}
  37. proc cap(cpp: SignalHandlerCpp): SignalContextCapability {.importcpp: "#->cap()".}
  38. proc newSignalHandler*(ep: Entrypoint; cb: HandlerProc): SignalHandler =
  39. ## Create a new signal handler. A label is recommended for
  40. ## debugging purposes. A signal handler will not be garbage
  41. ## collected until after it has been dissolved.
  42. result = SignalHandler(cb: cb)
  43. result.cpp.construct(ep, result)
  44. GCref result
  45. proc dissolve*(sig: SignalHandler) =
  46. ## Dissolve signal dispatcher from entrypoint.
  47. # TODO: =destroy?
  48. destruct sig.cpp
  49. sig.cb = nil # lose the callback
  50. GCunref sig
  51. proc cap*(sig: SignalHandler): SignalContextCapability =
  52. ## Signal context capability. Can be delegated to external components.
  53. sig.cpp.cap
  54. proc submit*(cap: SignalContextCapability) {.
  55. importcpp: "Genode::Signal_transmitter(#).submit()".}
  56. ## Submit a signal to a context capability.
  57. proc nimHandleSignal(p: pointer) {.exportc.} =
  58. ## C symbol invoked by entrypoint during signal dispatch.
  59. cast[SignalHandler](p).cb()