Skip to content

Instantly share code, notes, and snippets.

@thesjg
Created June 3, 2011 23:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thesjg/1007350 to your computer and use it in GitHub Desktop.
Save thesjg/1007350 to your computer and use it in GitHub Desktop.
Basic kevent device API
/*
* Used to maintain information about processes that wish to be
* notified when I/O becomes possible.
*/
struct kev_filter {
struct kev_filter_entry_list kf_entry;
struct kev_filter_ops kf_ops;
caddr_t fo_hook;
};
struct kev_filter is embedded in struct cdev (cdev_t) as
si_filters member, subsystems without a device node (the
minority) will embed struct kev_filter manually.
Sample initialization of a kevent-enabled driver:
static void
log_drvinit(void *unused)
{
cdev_t log_dev;
static struct kev_filter_ops kev_log_fops = {
.fop_read = { logfiltread, KEV_FILTOP_NOTMP };
}
log_dev = make_dev(&log_ops, 0, UID_ROOT, GID_WHEEL, 0600, "klog");
kev_dev_filter_init(log_dev, kev_log_fops, NULL);
&logsoftc.sc_cdev = log_dev;
}
kev_dev_filter_init() takes the cdev from make_dev() and plugs
the correct bits in the correct places. The NULL here is a caddr_t hook
and will be passed to the filter functions when called.
From the kevent internals side, when adding a new filter entry the
lookup will go through the same basic process as now, the fo_kqfilter
(now renamed) wrapper will take a filter entry (struct
kev_filter_entry, previously a knote) and assign the appropriate ops
vector to the filter entry. The kevent subsystem will check the ops
vector after this call returns to determine viability. Previously the
"constructor" function in each driver setup the appropriate callback
for each filter type, the hook and as necessary returned an error
to indicate a filter type was unsupported, kevent internals now handles
all of this. In the case where devfs sits in the middle, it will
simply return the si_filters member from the cdev.
KNOTE currently operates against a list that is typically embedded
in a drivers softc, KNOTE will operate now against a struct kev_filter
and a new KNOTE_DEV wrapper will take a cdev_t.
Devices will now simply export a simple "event" filter for each type
of event they wish to support, like the following:
static boolean_t
logfiltread(struct kev_filter_note *fn, long hint, caddr_t hook)
{
boolean_t ret = FALSE;
crit_enter();
if (msgbufp->msg_bufr != msgbufp->msg_bufx)
ret = TRUE;
crit_exit();
return (ret);
}
When a device is torn down, the devfs internals will call
kev_dev_filter_destroy (kev_filter_destroy wrapper) and the kevent
subsystem will assume the responsibility of disposing of the
filter and any attached notes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment