kqueue.odin 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. //+build darwin, netbsd, openbsd, freebsd
  2. package kqueue
  3. when ODIN_OS == .Darwin {
  4. foreign import lib "system:System.framework"
  5. } else {
  6. foreign import lib "system:c"
  7. }
  8. import "base:intrinsics"
  9. import "core:c"
  10. import "core:sys/posix"
  11. KQ :: posix.FD
  12. kqueue :: proc() -> (kq: KQ, err: posix.Errno) {
  13. kq = _kqueue()
  14. if kq == -1 {
  15. err = posix.errno()
  16. }
  17. return
  18. }
  19. kevent :: proc(kq: KQ, change_list: []KEvent, event_list: []KEvent, timeout: ^posix.timespec) -> (n_events: c.int, err: posix.Errno) {
  20. n_events = _kevent(
  21. kq,
  22. raw_data(change_list),
  23. c.int(len(change_list)),
  24. raw_data(event_list),
  25. c.int(len(event_list)),
  26. timeout,
  27. )
  28. if n_events == -1 {
  29. err = posix.errno()
  30. }
  31. return
  32. }
  33. Flag :: enum _Flags_Backing {
  34. Add = log2(0x0001), // Add event to kq (implies .Enable).
  35. Delete = log2(0x0002), // Delete event from kq.
  36. Enable = log2(0x0004), // Enable event.
  37. Disable = log2(0x0008), // Disable event (not reported).
  38. One_Shot = log2(0x0010), // Only report one occurrence.
  39. Clear = log2(0x0020), // Clear event state after reporting.
  40. Receipt = log2(0x0040), // Force immediate event output.
  41. Dispatch = log2(0x0080), // Disable event after reporting.
  42. Error = log2(0x4000), // Error, data contains errno.
  43. EOF = log2(0x8000), // EOF detected.
  44. }
  45. Flags :: bit_set[Flag; _Flags_Backing]
  46. Filter :: enum _Filter_Backing {
  47. Read = _FILTER_READ, // Check for read availability on the file descriptor.
  48. Write = _FILTER_WRITE, // Check for write availability on the file descriptor.
  49. AIO = _FILTER_AIO, // Attached to AIO requests.
  50. VNode = _FILTER_VNODE, // Check for changes to the subject file.
  51. Proc = _FILTER_PROC, // Check for changes to the subject process.
  52. Signal = _FILTER_SIGNAL, // Check for signals delivered to the process.
  53. Timer = _FILTER_TIMER, // Timers.
  54. }
  55. RW_Flag :: enum u32 {
  56. Low_Water_Mark = log2(0x00000001),
  57. }
  58. RW_Flags :: bit_set[RW_Flag; u32]
  59. VNode_Flag :: enum u32 {
  60. Delete = log2(0x00000001), // Deleted.
  61. Write = log2(0x00000002), // Contents changed.
  62. Extend = log2(0x00000004), // Size increased.
  63. Attrib = log2(0x00000008), // Attributes changed.
  64. Link = log2(0x00000010), // Link count changed.
  65. Rename = log2(0x00000020), // Renamed.
  66. Revoke = log2(0x00000040), // Access was revoked.
  67. }
  68. VNode_Flags :: bit_set[VNode_Flag; u32]
  69. Proc_Flag :: enum u32 {
  70. Exit = log2(0x80000000), // Process exited.
  71. Fork = log2(0x40000000), // Process forked.
  72. Exec = log2(0x20000000), // Process exec'd.
  73. Signal = log2(0x08000000), // Shared with `Filter.Signal`.
  74. }
  75. Proc_Flags :: bit_set[Proc_Flag; u32]
  76. Timer_Flag :: enum u32 {
  77. Seconds = log2(0x00000001), // Data is seconds.
  78. USeconds = log2(0x00000002), // Data is microseconds.
  79. NSeconds = log2(_NOTE_NSECONDS), // Data is nanoseconds.
  80. Absolute = log2(_NOTE_ABSOLUTE), // Absolute timeout.
  81. }
  82. Timer_Flags :: bit_set[Timer_Flag; u32]
  83. when ODIN_OS == .Darwin {
  84. _Filter_Backing :: distinct i16
  85. _Flags_Backing :: distinct u16
  86. _FILTER_READ :: -1
  87. _FILTER_WRITE :: -2
  88. _FILTER_AIO :: -3
  89. _FILTER_VNODE :: -4
  90. _FILTER_PROC :: -5
  91. _FILTER_SIGNAL :: -6
  92. _FILTER_TIMER :: -7
  93. _NOTE_NSECONDS :: 0x00000004
  94. _NOTE_ABSOLUTE :: 0x00000008
  95. KEvent :: struct #align(4) {
  96. // Value used to identify this event. The exact interpretation is determined by the attached filter.
  97. ident: uintptr,
  98. // Filter for event.
  99. filter: Filter,
  100. // General flags.
  101. flags: Flags,
  102. // Filter specific flags.
  103. fflags: struct #raw_union {
  104. rw: RW_Flags,
  105. vnode: VNode_Flags,
  106. fproc: Proc_Flags,
  107. // vm: VM_Flags,
  108. timer: Timer_Flags,
  109. },
  110. // Filter specific data.
  111. data: c.long /* intptr_t */,
  112. // Opaque user data passed through the kernel unchanged.
  113. udata: rawptr,
  114. }
  115. } else when ODIN_OS == .FreeBSD {
  116. _Filter_Backing :: distinct i16
  117. _Flags_Backing :: distinct u16
  118. _FILTER_READ :: -1
  119. _FILTER_WRITE :: -2
  120. _FILTER_AIO :: -3
  121. _FILTER_VNODE :: -4
  122. _FILTER_PROC :: -5
  123. _FILTER_SIGNAL :: -6
  124. _FILTER_TIMER :: -7
  125. _NOTE_NSECONDS :: 0x00000004
  126. _NOTE_ABSOLUTE :: 0x00000008
  127. KEvent :: struct {
  128. // Value used to identify this event. The exact interpretation is determined by the attached filter.
  129. ident: uintptr,
  130. // Filter for event.
  131. filter: Filter,
  132. // General flags.
  133. flags: Flags,
  134. // Filter specific flags.
  135. fflags: struct #raw_union {
  136. rw: RW_Flags,
  137. vnode: VNode_Flags,
  138. fproc: Proc_Flags,
  139. // vm: VM_Flags,
  140. timer: Timer_Flags,
  141. },
  142. // Filter specific data.
  143. data: i64,
  144. // Opaque user data passed through the kernel unchanged.
  145. udata: rawptr,
  146. // Extensions.
  147. ext: [4]u64,
  148. }
  149. } else when ODIN_OS == .NetBSD {
  150. _Filter_Backing :: distinct u32
  151. _Flags_Backing :: distinct u32
  152. _FILTER_READ :: 0
  153. _FILTER_WRITE :: 1
  154. _FILTER_AIO :: 2
  155. _FILTER_VNODE :: 3
  156. _FILTER_PROC :: 4
  157. _FILTER_SIGNAL :: 5
  158. _FILTER_TIMER :: 6
  159. _NOTE_NSECONDS :: 0x00000003
  160. _NOTE_ABSOLUTE :: 0x00000010
  161. KEvent :: struct #align(4) {
  162. // Value used to identify this event. The exact interpretation is determined by the attached filter.
  163. ident: uintptr,
  164. // Filter for event.
  165. filter: Filter,
  166. // General flags.
  167. flags: Flags,
  168. // Filter specific flags.
  169. fflags: struct #raw_union {
  170. rw: RW_Flags,
  171. vnode: VNode_Flags,
  172. fproc: Proc_Flags,
  173. // vm: VM_Flags,
  174. timer: Timer_Flags,
  175. },
  176. // Filter specific data.
  177. data: i64,
  178. // Opaque user data passed through the kernel unchanged.
  179. udata: rawptr,
  180. // Extensions.
  181. ext: [4]u64,
  182. }
  183. } else when ODIN_OS == .OpenBSD {
  184. _Filter_Backing :: distinct i16
  185. _Flags_Backing :: distinct u16
  186. _FILTER_READ :: -1
  187. _FILTER_WRITE :: -2
  188. _FILTER_AIO :: -3
  189. _FILTER_VNODE :: -4
  190. _FILTER_PROC :: -5
  191. _FILTER_SIGNAL :: -6
  192. _FILTER_TIMER :: -7
  193. _NOTE_NSECONDS :: 0x00000003
  194. _NOTE_ABSOLUTE :: 0x00000010
  195. KEvent :: struct #align(4) {
  196. // Value used to identify this event. The exact interpretation is determined by the attached filter.
  197. ident: uintptr,
  198. // Filter for event.
  199. filter: Filter,
  200. // General flags.
  201. flags: Flags,
  202. // Filter specific flags.
  203. fflags: struct #raw_union {
  204. rw: RW_Flags,
  205. vnode: VNode_Flags,
  206. fproc: Proc_Flags,
  207. // vm: VM_Flags,
  208. timer: Timer_Flags,
  209. },
  210. // Filter specific data.
  211. data: i64,
  212. // Opaque user data passed through the kernel unchanged.
  213. udata: rawptr,
  214. }
  215. }
  216. @(private)
  217. log2 :: intrinsics.constant_log2
  218. foreign lib {
  219. @(link_name="kqueue")
  220. _kqueue :: proc() -> KQ ---
  221. @(link_name="kevent")
  222. _kevent :: proc(kq: KQ, change_list: [^]KEvent, n_changes: c.int, event_list: [^]KEvent, n_events: c.int, timeout: ^posix.timespec) -> c.int ---
  223. }