The Wayback Machine - https://web.archive.org/web/20171226212235/http://man.openbsd.org/kqueue.2
kqueue,
kevent,
EV_SET —
kernel event notification mechanism
#include
<sys/types.h>
#include
<sys/event.h>
#include
<sys/time.h>
int
kqueue(
void);
int
kevent(
int
kq,
const struct
kevent *changelist,
int nchanges,
struct kevent
*eventlist,
int
nevents,
const
struct timespec *timeout);
EV_SET(
&kev,
ident,
filter,
flags,
fflags,
data,
udata);
kqueue() provides a generic method of notifying the
user when an event happens or a condition holds, based on the results of small
pieces of kernel code termed “filters”. A kevent is identified
by the (ident, filter) pair; there may only be one unique kevent per kqueue.
The filter is executed upon the initial registration of a kevent in order to
detect whether a preexisting condition is present, and is also executed
whenever an event is passed to the filter for evaluation. If the filter
determines that the condition should be reported, then the kevent is placed on
the kqueue for the user to retrieve.
The filter is also run when the user attempts to retrieve the kevent from the
kqueue. If the filter indicates that the condition that triggered the event no
longer holds, the kevent is removed from the kqueue and is not returned.
Multiple events which trigger the filter do not result in multiple kevents being
placed on the kqueue; instead, the filter will aggregate the events into a
single
struct kevent. Calling
close() on a file descriptor will remove any
kevents that reference the descriptor.
kqueue() creates a new kernel event queue and
returns a descriptor. The queue is not inherited by a child created with
fork(2). Similarly, kqueues cannot
be passed across UNIX-domain sockets.
kevent() is used to register events with the queue,
and return any pending events to the user.
changelist is a pointer to an array of
kevent structures, as defined in
<sys/event.h>.
All changes contained in the
changelist are
applied before any pending events are read from the queue.
nchanges gives the size of
changelist.
eventlist is a pointer to an array of kevent
structures.
nevents determines the size of
eventlist. When
nevents is zero,
kevent() will return immediately even if there is
a
timeout specified unlike
select(2). If
timeout is a non-null pointer, it specifies a
maximum interval to wait for an event, which will be interpreted as a
struct timespec. If
timeout is a null pointer,
kevent() waits indefinitely. To effect a poll,
the
timeout argument should be non-null,
pointing to a zero-valued
timespec structure.
The same array may be used for the
changelist
and
eventlist.
EV_SET() is a macro which is provided for ease of
initializing a kevent structure.
The
kevent structure is defined as:
struct kevent {
uintptr_t ident; /* identifier for this event */
short filter; /* filter for event */
u_short flags; /* action flags for kqueue */
u_int fflags; /* filter flag value */
int64_t data; /* filter data value */
void *udata; /* opaque user data identifier */
};
The fields of
struct kevent are:
-
-
- ident
- Value used to identify this event. The exact interpretation
is determined by the attached filter, but often is a file descriptor.
-
-
- filter
- Identifies the kernel filter used to process this event.
The pre-defined system filters are described below.
-
-
- flags
- Actions to perform on the event.
-
-
- fflags
- Filter-specific flags.
-
-
- data
- Filter-specific data value.
-
-
- udata
- Opaque user-defined value passed through the kernel
unchanged.
The
flags field can contain the following
values:
-
-
EV_ADD
- Adds the event to the kqueue. Re-adding an existing event
will modify the parameters of the original event, and not result in a
duplicate entry. Adding an event automatically enables it, unless
overridden by the
EV_DISABLE flag.
-
-
EV_ENABLE
- Permit kevent() to return the
event if it is triggered.
-
-
EV_DISABLE
- Disable the event so kevent()
will not return it. The filter itself is not disabled.
-
-
EV_DISPATCH
- Disable the event source immediately after delivery of an
event. See
EV_DISABLE above.
-
-
EV_DELETE
- Removes the event from the kqueue. Events which are
attached to file descriptors are automatically deleted on the last close
of the descriptor.
-
-
EV_RECEIPT
- Causes kevent() to return with
EV_ERROR set without draining any
pending events after updating events in the kqueue. When a filter is
successfully added the data field will be
zero. This flag is useful for making bulk changes to a kqueue.
-
-
EV_ONESHOT
- Causes the event to return only the first occurrence of the
filter being triggered. After the user retrieves the event from the
kqueue, it is deleted.
-
-
EV_CLEAR
- After the event is retrieved by the user, its state is
reset. This is useful for filters which report state transitions instead
of the current state. Note that some filters may automatically set this
flag internally.
-
-
EV_EOF
- Filters may set this flag to indicate filter-specific EOF
condition.
-
-
EV_ERROR
- See RETURN
VALUES below.
The predefined system filters are listed below. Arguments may be passed to and
from the filter via the
fflags and
data fields in the kevent structure.
-
-
EVFILT_READ
- Takes a descriptor as the identifier, and returns whenever
there is data available to read. The behavior of the filter is slightly
different depending on the descriptor type.
-
-
- Sockets
- Sockets which have previously been passed to
listen() return when there is an incoming
connection pending. data contains the
size of the listen backlog.
Other socket descriptors return when there is data to be read, subject
to the
SO_RCVLOWAT value of the
socket buffer. This may be overridden with a per-filter low water mark
at the time the filter is added by setting the
NOTE_LOWAT flag in
fflags, and specifying the new low
water mark in data. On return,
data contains the number of bytes in
the socket buffer.
If the read direction of the socket has shutdown, then the filter also
sets EV_EOF in
flags, and returns the socket error
(if any) in fflags. It is possible
for EOF to be returned (indicating the connection is gone) while there
is still data pending in the socket buffer.
-
-
- Vnodes
- Returns when the file pointer is not at the end of
file. data contains the offset from
current position to end of file, and may be negative. If
NOTE_EOF is set in
fflags,
kevent() will also return when the file
pointer is at the end of file. The end of file condition is indicated
by the presence of NOTE_EOF in
fflags on return.
-
-
- FIFOs, Pipes
- Returns when there is data to read;
data contains the number of bytes
available.
When the last writer disconnects, the filter will set
EV_EOF in
flags. This may be cleared by passing
in EV_CLEAR, at which point the
filter will resume waiting for data to become available before
returning.
-
-
- BPF devices
- Returns when the BPF buffer is full, the BPF timeout
has expired, or when the BPF has “immediate mode”
enabled and there is any data to read;
data contains the number of bytes
available.
-
-
EVFILT_WRITE
- Takes a descriptor as the identifier, and returns whenever
it is possible to write to the descriptor. For sockets, pipes, and FIFOs,
data will contain the amount of space
remaining in the write buffer. The filter will set
EV_EOF when the reader disconnects, and
for the FIFO case, this may be cleared by use of
EV_CLEAR. Note that this filter is not
supported for vnodes or BPF devices.
For sockets, the low water mark and socket error handling is identical to
the EVFILT_READ case.
-
-
EVFILT_VNODE
- Takes a file descriptor as the identifier and the events to
watch for in fflags, and returns when one
or more of the requested events occurs on the descriptor. The events to
monitor are:
-
-
NOTE_DELETE
- unlink() was called on the
file referenced by the descriptor.
-
-
NOTE_WRITE
- A write occurred on the file referenced by the
descriptor.
-
-
NOTE_EXTEND
- The file referenced by the descriptor was
extended.
-
-
NOTE_TRUNCATE
- The file referenced by the descriptor was
truncated.
-
-
NOTE_ATTRIB
- The file referenced by the descriptor had its
attributes changed.
-
-
NOTE_LINK
- The link count on the file changed.
-
-
NOTE_RENAME
- The file referenced by the descriptor was renamed.
-
-
NOTE_REVOKE
- Access to the file was revoked via
revoke(2) or the
underlying file system was unmounted.
On return, fflags contains the events which
triggered the filter.
-
-
EVFILT_PROC
- Takes the process ID to monitor as the identifier and the
events to watch for in fflags, and
returns when the process performs one or more of the requested events. If
a process can normally see another process, it can attach an event to it.
The events to monitor are:
-
-
NOTE_EXIT
- The process has exited. The exit status will be stored
in data in the same format as the
status set by
wait(2).
-
-
NOTE_FORK
- The process has called
fork().
-
-
NOTE_EXEC
- The process has executed a new process via
execve(2) or similar
call.
-
-
NOTE_TRACK
- Follow a process across
fork() calls. The parent process will
return with
NOTE_FORK set in the
fflags field, while the child process
will return with NOTE_CHILD set in
fflags and the parent PID in
data.
-
-
NOTE_TRACKERR
- This flag is returned if the system was unable to
attach an event to the child process, usually due to resource
limitations.
On return, fflags contains the events which
triggered the filter.
-
-
EVFILT_SIGNAL
- Takes the signal number to monitor as the identifier and
returns when the given signal is delivered to the process. This coexists
with the signal() and
sigaction() facilities, and has a lower
precedence. The filter will record all attempts to deliver a signal to a
process, even if the signal has been marked as
SIG_IGN. Event notification happens
after normal signal delivery processing.
data returns the number of times the
signal has occurred since the last call to
kevent(). This filter automatically sets the
EV_CLEAR flag internally.
-
-
EVFILT_TIMER
- Establishes an arbitrary timer identified by
ident. When adding a timer,
data specifies the timeout period in
milliseconds. The timer will be periodic unless
EV_ONESHOT is specified. On return,
data contains the number of times the
timeout has expired since the last call to
kevent(). This filter automatically sets the
EV_CLEAR flag internally.
kqueue() creates a new kernel event queue and
returns a file descriptor. If there was an error creating the kernel event
queue, a value of -1 is returned and errno set.
kevent() returns the number of events placed in the
eventlist, up to the value given by
nevents. If an error occurs while processing
an element of the
changelist and there is
enough room in the
eventlist, then the event
will be placed in the
eventlist with
EV_ERROR set in
flags and the system error in
data. Otherwise,
-1 will be returned, and
errno will be set to indicate the error
condition. If the time limit expires, then
kevent() returns 0.
The
kqueue() function fails if:
-
-
- [
ENOMEM]
- The kernel failed to allocate enough memory for the kernel
queue.
-
-
- [
EMFILE]
- The per-process descriptor table is full.
-
-
- [
ENFILE]
- The system file table is full.
The
kevent() function fails if:
-
-
- [
EACCES]
- The process does not have permission to register a
filter.
-
-
- [
EFAULT]
- There was an error reading or writing the
kevent structure.
-
-
- [
EBADF]
- The specified descriptor is invalid.
-
-
- [
EINTR]
- A signal was delivered before the timeout expired and
before any events were placed on the kqueue for return.
-
-
- [
EINVAL]
- The specified time limit or filter is invalid.
-
-
- [
ENOENT]
- The event could not be found to be modified or
deleted.
-
-
- [
ENOMEM]
- No memory was available to register the event.
-
-
- [
ESRCH]
- The specified process to attach to does not exist.
poll(2),
read(2),
select(2),
sigaction(2),
wait(2),
write(2),
signal(3)
The
kqueue() and
kevent() functions first appeared in
FreeBSD 4.1.
The
kqueue() system and this manual page were
written by
Jonathan Lemon
<
jlemon@FreeBSD.org>.
It is currently not possible to watch FIFOs or AIO that reside on anything but a
UFS file system. Watching a vnode is possible on UFS, NFS and MS-DOS file
systems.
The
timeout value is limited to 24 hours;
longer timeouts will be silently reinterpreted as 24 hours.