Created
June 3, 2011 23:24
-
-
Save thesjg/1007350 to your computer and use it in GitHub Desktop.
Basic kevent device API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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