# std/selectors

Theme:

- Manual
- Standard library
- Index
- Compiler docs
- Fusion docs
- devel, stable

Search:
Source Edit

This module allows high-level and efficient I/O multiplexing.

Supported OS primitives: `epoll`, `kqueue`, `poll` and Windows `select`.

To use threadsafe version of this module, it needs to be compiled with both `-d:threadsafe` and `--threads:on` options.

Supported features: files, sockets, pipes, timers, processes, signals and user events.

Fully supported OS: MacOSX, FreeBSD, OpenBSD, NetBSD, Linux (except for Android).

Partially supported OS: Windows (only sockets and user events), Solaris (files, sockets, handles and user events). Android (files, sockets, handles and user events).

By default, the implementation is chosen based on the target platform; you can pass `-d:nimIoselector=value` to override it. Accepted values are "epoll", "kqueue", "poll", and "select".

TODO: `/dev/poll`, `event ports` and filesystem events.

# Imports

nativesockets, oserrors, assertions

# Types

    Event {.pure.} = enum
      Read,                     ## Descriptor is available for read
      Write,                    ## Descriptor is available for write
      Timer,                    ## Timer descriptor is completed
      Signal,                   ## Signal is raised
      Process,                  ## Process is finished
      Vnode,                    ## BSD specific file change
      User,                     ## User event is raised
      Error,                    ## Error occurred while waiting for descriptor
      VnodeWrite,               ## NOTE_WRITE (BSD specific, write to file occurred)
      VnodeDelete,              ## NOTE_DELETE (BSD specific, unlink of file occurred)
      VnodeExtend,              ## NOTE_EXTEND (BSD specific, file extended)
      VnodeAttrib,              ## NOTE_ATTRIB (BSD specific, file attributes changed)
      VnodeLink,                ## NOTE_LINK (BSD specific, file link count changed)
      VnodeRename,              ## NOTE_RENAME (BSD specific, file renamed)
      VnodeRevoke                ## NOTE_REVOKE (BSD specific, file revoke occurred)

  An enum which hold event types Source Edit

    IOSelectorsException = object of CatchableError

  Exception that is raised if an IOSelectors error occurs. Source Edit

    ReadyKey = object
      fd*: int                   ## file/socket descriptor
      events*: set[Event]        ## set of events
      errorCode*: OSErrorCode    ## additional error code information for
                                 ## Error events

  An object which holds result for descriptor Source Edit

    SelectEvent = object

  An object which holds user defined event Source Edit

    Selector[T] = ref object

  An object which holds descriptors to be checked for read/write status Source Edit

# Consts

    ioselSupportedPlatform = true

  This constant is used to determine whether the destination platform is fully supported by `ioselectors` module. Source Edit

# Procs

    proc close(ev: SelectEvent) {....raises: [], tags: [], forbids: [].}

  Closes user-defined event `ev`. Source Edit

    proc close[T](s: Selector[T])

  Closes the selector. Source Edit

    proc contains[T](s: Selector[T]; fd: SocketHandle | int): bool {.inline.}

  Determines whether selector contains a file descriptor. Source Edit

    proc getData[T](s: Selector[T]; fd: SocketHandle | int): var T

  Retrieves application-defined `data` associated with descriptor `fd`. If specified descriptor `fd` is not registered, empty/default value will be returned. Source Edit

    proc getFd[T](s: Selector[T]): int

  Retrieves the underlying selector's file descriptor.

  For poll and select selectors `-1` is returned.

  Source Edit

    proc newSelectEvent(): SelectEvent {....raises: [], tags: [], forbids: [].}

  Creates a new user-defined event. Source Edit

    proc newSelector[T](): Selector[T]

  Creates a new selector Source Edit

    proc registerEvent[T](s: Selector[T]; ev: SelectEvent; data: T)

  Registers selector event `ev` in selector `s`.

  The `data` is application-defined data, which will be passed when `ev` happens.

  Source Edit

    proc registerHandle[T](s: Selector[T]; fd: int | SocketHandle;
                           events: set[Event]; data: T)

  Registers file/socket descriptor `fd` to selector `s` with events set in `events`. The `data` is application-defined data, which will be passed when an event is triggered. Source Edit

    proc registerProcess[T](s: Selector[T]; pid: int; data: T): int {.discardable.}

  Registers a process id (pid) notification (when process has exited) in selector `s`.

  The `data` is application-defined data, which will be passed when process with `pid` has exited.

  Returns the file descriptor for the registered signal.

  Source Edit

    proc registerSignal[T](s: Selector[T]; signal: int; data: T): int {.discardable.}

  Registers Unix signal notification with `signal` to selector `s`.

  The `data` is application-defined data, which will be passed when signal raises.

  Returns the file descriptor for the registered signal.

  Note: This function is not supported on `Windows`.

  Source Edit

    proc registerTimer[T](s: Selector[T]; timeout: int; oneshot: bool; data: T): int {.
        discardable.}

  Registers timer notification with `timeout` (in milliseconds) to selector `s`.

  If `oneshot` is `true`, timer will be notified only once.

  Set `oneshot` to `false` if you want periodic notifications.

  The `data` is application-defined data, which will be passed, when the timer is triggered.

  Returns the file descriptor for the registered timer.

  Source Edit

    proc registerVnode[T](s: Selector[T]; fd: cint; events: set[Event]; data: T)

  Registers selector BSD/MacOSX specific vnode events for file descriptor `fd` and events `events`. `data` application-defined data, which to be passed, when vnode event happens.

  Note: This function is supported only by BSD and MacOSX.

  Source Edit

    proc select[T](s: Selector[T]; timeout: int): seq[ReadyKey]

  Waits for events registered in selector `s`.

  The `timeout` argument specifies the maximum number of milliseconds the function will be blocked for if no events are ready. Specifying a timeout of `-1` causes the function to block indefinitely.

  Returns a list of triggered events.

  Source Edit

    proc selectInto[T](s: Selector[T]; timeout: int;
                       results: var openArray[ReadyKey]): int

  Waits for events registered in selector `s`.

  The `timeout` argument specifies the maximum number of milliseconds the function will be blocked for if no events are ready. Specifying a timeout of `-1` causes the function to block indefinitely. All available events will be stored in `results` array.

  Returns number of triggered events.

  Source Edit

    proc setData[T](s: Selector[T]; fd: SocketHandle | int; data: var T): bool

  Associate application-defined `data` with descriptor `fd`.

  Returns `true`, if data was successfully updated, `false` otherwise.

  Source Edit

    proc trigger(ev: SelectEvent) {....raises: [], tags: [], forbids: [].}

  Trigger event `ev`. Source Edit

    proc unregister[T](s: Selector[T]; ev: SelectEvent)

  Unregisters user-defined event `ev` from selector `s`. Source Edit

    proc unregister[T](s: Selector[T]; fd: int | SocketHandle | cint)

  Unregisters file/socket descriptor `fd` from selector `s`. Source Edit

    proc updateHandle[T](s: Selector[T]; fd: int | SocketHandle; events: set[Event])

  Update file/socket descriptor `fd`, registered in selector `s` with new events set `event`. Source Edit

# Templates

    template isEmpty[T](s: Selector[T]): bool

  Returns `true`, if there are no registered events or descriptors in selector. Source Edit

    template withData[T](s: Selector[T]; fd: SocketHandle | int;
                         value, body1, body2: untyped)

  Retrieves the application-data assigned with descriptor `fd` to `value`. This `value` can be modified in the scope of the `withData` call.

      s.withData(fd, value) do:
        # block is executed only if `fd` registered in selector `s`.
        value.uid = 1000
      do:
        # block is executed if `fd` not registered in selector `s`.
        raise

  Source Edit

    template withData[T](s: Selector[T]; fd: SocketHandle | int;
                         value, body: untyped)

  Retrieves the application-data assigned with descriptor `fd` to `value`. This `value` can be modified in the scope of the `withData` call.

      s.withData(fd, value) do:
        # block is executed only if `fd` registered in selector `s`
        value.uid = 1000

  Source Edit