summary refs log tree commit diff stats
path: root/lib/posix/kqueue.nim
diff options
context:
space:
mode:
Diffstat (limited to 'lib/posix/kqueue.nim')
-rw-r--r--lib/posix/kqueue.nim161
1 files changed, 161 insertions, 0 deletions
diff --git a/lib/posix/kqueue.nim b/lib/posix/kqueue.nim
new file mode 100644
index 000000000..2450cdb42
--- /dev/null
+++ b/lib/posix/kqueue.nim
@@ -0,0 +1,161 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2016 Eugene Kabanov
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+from std/posix import Timespec
+
+when defined(macosx) or defined(freebsd) or defined(openbsd) or
+     defined(dragonfly):
+  const
+    EVFILT_READ*     = -1
+    EVFILT_WRITE*    = -2
+    EVFILT_AIO*      = -3 ## attached to aio requests
+    EVFILT_VNODE*    = -4 ## attached to vnodes
+    EVFILT_PROC*     = -5 ## attached to struct proc
+    EVFILT_SIGNAL*   = -6 ## attached to struct proc
+    EVFILT_TIMER*    = -7 ## timers
+elif defined(netbsd):
+  const
+    EVFILT_READ*     = 0
+    EVFILT_WRITE*    = 1
+    EVFILT_AIO*      = 2 ## attached to aio requests
+    EVFILT_VNODE*    = 3 ## attached to vnodes
+    EVFILT_PROC*     = 4 ## attached to struct proc
+    EVFILT_SIGNAL*   = 5 ## attached to struct proc
+    EVFILT_TIMER*    = 6 ## timers (in ms)
+when defined(macosx):
+  const
+    EVFILT_MACHPORT* = -8  ## Mach portsets
+    EVFILT_FS*       = -9  ## filesystem events
+    EVFILT_USER*     = -10 ## user events
+    EVFILT_VM        = -12 ## virtual memory events
+elif defined(freebsd):
+  const
+    EVFILT_FS*       = -9  ## filesystem events
+    EVFILT_LIO*      = -10 ## attached to lio requests
+    EVFILT_USER*     = -11 ## user events
+elif defined(dragonfly):
+  const
+    EVFILT_EXCEPT*   = -8  ## exceptional conditions
+    EVFILT_USER*     = -9  ## user events
+    EVFILT_FS*       = -10 ## filesystem events
+
+# Actions:
+const
+  EV_ADD*      = 0x0001 ## Add event to queue (implies enable).
+                        ## Re-adding an existing element modifies it.
+  EV_DELETE*   = 0x0002 ## Delete event from queue.
+  EV_ENABLE*   = 0x0004 ## Enable event.
+  EV_DISABLE*  = 0x0008 ## Disable event (not reported).
+
+# Flags:
+const
+  EV_ONESHOT*  = 0x0010 ## Only report one occurrence.
+  EV_CLEAR*    = 0x0020 ## Clear event state after reporting.
+  EV_RECEIPT*  = 0x0040 ## Force EV_ERROR on success, data == 0
+  EV_DISPATCH* = 0x0080 ## Disable event after reporting.
+
+  EV_SYSFLAGS* = 0xF000 ## Reserved by system
+  EV_DROP*     = 0x1000 ## Not should be dropped
+  EV_FLAG1*    = 0x2000 ## Filter-specific flag
+
+# Return values:
+const
+  EV_EOF*      = 0x8000 ## EOF detected
+  EV_ERROR*    = 0x4000 ## Error, data contains errno
+  EV_NODATA*   = 0x1000 ## EOF and no more data
+
+when defined(macosx) or defined(freebsd) or defined(dragonfly):
+  # EVFILT_USER is not supported by OpenBSD and NetBSD
+  #
+  # data/hint flags/masks for EVFILT_USER, shared with userspace
+  #
+  # On input, the top two bits of fflags specifies how the lower twenty four
+  # bits should be applied to the stored value of fflags.
+  #
+  # On output, the top two bits will always be set to NOTE_FFNOP and the
+  # remaining twenty four bits will contain the stored fflags value.
+  const
+    NOTE_FFNOP*      = 0x00000000'u32 ## ignore input fflags
+    NOTE_FFAND*      = 0x40000000'u32 ## AND fflags
+    NOTE_FFOR*       = 0x80000000'u32 ## OR fflags
+    NOTE_FFCOPY*     = 0xc0000000'u32 ## copy fflags
+    NOTE_FFCTRLMASK* = 0xc0000000'u32 ## masks for operations
+    NOTE_FFLAGSMASK* = 0x00ffffff'u32
+
+    NOTE_TRIGGER*    = 0x01000000'u32 ## Cause the event to be triggered
+                                      ## for output.
+
+# data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
+const
+  NOTE_LOWAT*      = 0x0001 ## low water mark
+
+# data/hint flags for EVFILT_VNODE, shared with userspace
+const
+  NOTE_DELETE*     = 0x0001 ## vnode was removed
+  NOTE_WRITE*      = 0x0002 ## data contents changed
+  NOTE_EXTEND*     = 0x0004 ## size increased
+  NOTE_ATTRIB*     = 0x0008 ## attributes changed
+  NOTE_LINK*       = 0x0010 ## link count changed
+  NOTE_RENAME*     = 0x0020 ## vnode was renamed
+  NOTE_REVOKE*     = 0x0040 ## vnode access was revoked
+
+# data/hint flags for EVFILT_PROC, shared with userspace
+const
+  NOTE_EXIT*       = 0x80000000'u32 ## process exited
+  NOTE_FORK*       = 0x40000000'u32 ## process forked
+  NOTE_EXEC*       = 0x20000000'u32 ## process exec'd
+  NOTE_PCTRLMASK*  = 0xf0000000'u32 ## mask for hint bits
+  NOTE_PDATAMASK*  = 0x000fffff'u32 ## mask for pid
+
+# additional flags for EVFILT_PROC
+const
+  NOTE_TRACK*      = 0x00000001'u32 ## follow across forks
+  NOTE_TRACKERR*   = 0x00000002'u32 ## could not track child
+  NOTE_CHILD*      = 0x00000004'u32 ## am a child process
+
+when defined(macosx) or defined(freebsd):
+  # additional flags for EVFILE_TIMER
+  const
+    NOTE_SECONDS*    = 0x00000001'u32 ## data is seconds
+    NOTE_MSECONDS*   = 0x00000002'u32 ## data is milliseconds
+    NOTE_USECONDS*   = 0x00000004'u32 ## data is microseconds
+    NOTE_NSECONDS*   = 0x00000008'u32 ## data is nanoseconds
+else:
+  # NetBSD and OpenBSD doesn't support NOTE_{TIME} constants, but
+  # support EVFILT_TIMER with granularity of milliseconds.
+  const
+    NOTE_MSECONDS*   = 0x00000000'u32
+
+type
+  ## This define not fully satisfy NetBSD "struct kevent"
+  ## but it works and tested.
+  KEvent* {.importc: "struct kevent",
+            header: """#include <sys/types.h>
+                       #include <sys/event.h>
+                       #include <sys/time.h>""", pure, final.} = object
+    ident*  : uint     ## identifier for this event  (uintptr_t)
+    filter* : cshort   ## filter for event
+    flags*  : cushort  ## general flags
+    fflags* : cuint    ## filter-specific flags
+    data*   : int      ## filter-specific data  (intptr_t)
+    udata*  : pointer  ## opaque user data identifier
+
+proc kqueue*(): cint {.importc: "kqueue", header: "<sys/event.h>".}
+  ## Creates new queue and returns its descriptor.
+
+proc kevent*(kqFD: cint,
+             changelist: ptr KEvent, nchanges: cint,
+             eventlist: ptr KEvent, nevents: cint, timeout: ptr Timespec): cint
+     {.importc: "kevent", header: "<sys/event.h>".}
+  ## Manipulates queue for given `kqFD` descriptor.
+
+proc EV_SET*(event: ptr KEvent, ident: uint, filter: cshort, flags: cushort,
+             fflags: cuint, data: int, udata: pointer)
+     {.importc: "EV_SET", header: "<sys/event.h>".}
+  ## Fills event with given data.