#include <sys/event.h> int
kqueue_add_filteropts (int filt struct filterops *filtops); int
kqueue_del_filteropts (int filt); int
kqfd_register (int fd struct kevent *kev struct thread *td int waitok); void
knote_fdclose (struct thread *td int fd); void
knlist_add (struct knlist *knl struct knote *kn int islocked); void
knlist_remove (struct knlist *knl struct knote *kn int islocked); void
knlist_remove_inevent (struct knlist *knl struct knote *kn); int
knlist_empty (struct knlist *knl); void
Fo knlist_init
Fa struct knlist *knl
Fa void *lock
Fa void lp]*kl_lockrp]lp]void *rp]
Fa void lp]*kl_unlockrp]lp]void *rp]
Fa int lp]*kl_lockedrp]lp]void *rp]
Fc Ft void
knlist_destroy (struct knlist *knl); void
knlist_clear (struct knlist *knl int islocked); void
knlist_delete (struct knlist *knl struct thread *td int islocked); void
KNOTE_LOCKED (struct knlist *knl long hint); void
KNOTE_UNLOCKED (struct knlist *knl long hint);
DESCRIPTION
The functions
kqueue_add_filteropts ();
and
kqueue_del_filteropts ();
allow for the addition and removal of a filter type.
The filter is statically defined by the
EVFILT_*
macros.
The function
kqueue_add_filteropts ();
will make
Fa filt
available.
The
Vt struct filterops
has the following members:
f_isfd
If
f_isfd
is set,
ident
in
Vt struct kevent
is taken to be a file descriptor.
In this case, the
Vt knote
passed into
f_attach
will have the
kn_fp
member initialized to the
Vt struct file *
that represents the file descriptor.
f_attach
The
f_attach
function will be called when attaching a
Vt knote
to the object.
The method should call
knlist_add ();
to add the
Vt knote
to the list that was initialized with
knlist_init (.);
The call to
knlist_add ();
is only necessary if the object can have multiple
Vt knotes
associated with it.
If there is no
Vt knlist
to call
knlist_add ();
with, the function
f_attach
must clear the
KN_DETACHED
bit of
kn_status
in the
Vt knote .
The function shall return 0 on success, or appropriate error for the failure.
During
f_attach
it is valid to change the
kn_fops
pointer to a different pointer.
This will change the
f_event
and
f_detach
functions called when processing the
Vt knote .
f_detach
The
f_detach
function will be called to detach the
Vt knote
if the
Vt knote
has not already been detached by a call to
knlist_remove (.);
f_event
The
f_event
function will be called to update the status of the
Vt knote .
If the function returns 0, it will be assumed that the object is not
ready (or no longer ready) to be woken up.
The
Fa hint
argument will be 0 when scanning
Vt knotes
to see which are triggered.
Otherwise, the
Fa hint
argument will be the value passed to either
KNOTE_LOCKED
or
KNOTE_UNLOCKED
The
kn_data
value should be updated as necessary to reflect the current value, such as
number of bytes available for reading, or buffer space available for writing.
If the note needs to be removed,
knlist_remove_inevent ();
must be called.
The function
knlist_remove_inevent ();
will remove the note from the list, the
f_detach
function will not be called and the
Vt knote
will not be returned as an event.
Locks
must not
be acquired in
f_event
If a lock is required in
f_event
it must be obtained in the
Fa kl_lock
function of the
Vt knlist
that the
knote
was added to.
The function
kqfd_register ();
will register the
Vt kevent
on the kqueue file descriptor
Fa fd .
If it is safe to sleep,
Fa waitok
should be set.
The function
knote_fdclose ();
is used to delete all
Vt knotes
associated with
Fa fd .
Once returned, there will no longer be any
Vt knotes
associated with the
Fa fd .
The
Vt knotes
removed will never be returned from a
kevent(2)
call, so if userland uses the
Vt knote
to track resources, they will be leaked.
The
FILEDESC_LOCK ();
lock must be held over the call to
knote_fdclose ();
so that file descriptors cannot be added or removed.
The
knlist_ (*);
family of functions are for managing
Vt knotes
associated with an object.
A
Vt knlist
is not required, but is commonly used.
If used, the
Vt knlist
must be initialized with the
knlist_init ();
function.
If
Fa lock
is
NULL
an internal lock will be used and the remaining arguments will be ignored.
The
Fa kl_lock , kl_unlock
and
Fa kl_locked
functions will be used to manipulate a
Fa lock .
If the argument is
NULL
default routines operating on
Vt struct mtx *
will be used.
The
Vt knlist
structure may be embedded into the object structure.
The
Fa lock
will be held over calls to
f_event
If
NULL
is passed for the mutex, a private mutex will be used.
The function
knlist_empty ();
requires that a
Fa lock
be held.
The function
knlist_clear ();
is used to remove all
Vt knotes
associated with the list.
The
Fa islocked
argument declares if
Fa lock
has been acquired.
All
Vt knotes
will be marked as detached, and
EV_ONESHOT
will be set so that the
Vt knote
will be deleted after the next scan.
The
knlist_destroy ();
function is used to destroy a
Vt knlist .
There must be no
Vt knotes
associated with the
Vt knlist
Fn ( knlist_empty
returns true)
and no more
Vt knotes
may be attached to the object.
A
Vt knlist
may be emptied by calling
knlist_clear (.);
The macros
KNOTE_LOCKED ();
and
KNOTE_UNLOCKED ();
are used to notify
Vt knotes
about events associated with the object.
It will iterate over all
Vt knotes
on the list calling the
f_event
function associated with the
Vt knote .
The macro
KNOTE_LOCKED ();
must be used if the lock associated with the
Fa knl
passed in is held.
The function
KNOTE_UNLOCKED ();
will acquire the lock before iterating over the list of
Vt knotes .
RETURN VALUES
The function
kqueue_add_filteropts ();
will return zero on success,
Er EINVAL
in the case of an invalid
Fa filt ,
or
Er EEXIST
if the filter has already been installed.
The function
kqueue_del_filteropts ();
will return zero on success,
Er EINVAL
in the case of an invalid
Fa filt ,
or
Er EBUSY
if the filter is still in use.
The function
kqfd_register ();
will return zero on success,
Er EBADF
if the file descriptor is not a kqueue, or any of the possible values returned
by
kevent(2).