+static inline struct kqueue *knote_get_kq(struct knote *kn)
+{
+ if (!(kn->kn_kq_packed))
+ return 0;
+ else
+ return (struct kqueue *)((uintptr_t)(kn->kn_kq_packed) + (uintptr_t)VM_MIN_KERNEL_AND_KEXT_ADDRESS);
+}
+
+static inline void knote_set_kq(struct knote *kn, void *kq)
+{
+ if (!kq)
+ kn->kn_kq_packed = 0;
+ else {
+ uint64_t offset = ((uintptr_t)kq - (uintptr_t)VM_MIN_KERNEL_AND_KEXT_ADDRESS);
+ kn->kn_kq_packed = offset;
+ }
+}
+
+struct filt_process_s {
+ int fp_fd;
+ unsigned int fp_flags;
+ user_addr_t fp_data_out;
+ user_size_t fp_data_size;
+ user_size_t fp_data_resid;
+};
+typedef struct filt_process_s *filt_process_data_t;
+
+/*
+ * Filter operators
+ *
+ * These routines, provided by each filter, are called to attach, detach, deliver events,
+ * change/update filter registration and process/deliver events. They are called with the
+ * with a use-count referenced knote, with the kq unlocked. Here are more details:
+ *
+ * f_isfd -
+ * identifies if the "ident" field in the kevent structure is a file-descriptor.
+ *
+ * If so, the knote is associated with the file descriptor prior to attach and
+ * auto-removed when the file descriptor is closed (this latter behavior may change
+ * for EV_DISPATCH2 kevent types to allow delivery of events identifying unintended
+ * closes).
+ *
+ * Otherwise the knote is hashed by the ident and has no auto-close behavior.
+ *
+ * f_attach -
+ * called to attach the knote to the underlying object that will be delivering events
+ * through it when EV_ADD is supplied and no existing matching event is found
+ *
+ * provided a knote that is pre-attached to the fd or hashed (see above) but is
+ * specially marked to avoid concurrent access until the attach is complete. The
+ * kevent structure embedded in this knote has been filled in with a sanitized
+ * version of the user-supplied kevent data. However, the user-supplied filter-specific
+ * flags (fflags) and data fields have been moved into the knote's kn_sfflags and kn_sdata
+ * fields respectively. These are usually interpretted as a set of "interest" flags and
+ * data by each filter - to be matched against delivered events.
+ *
+ * The attach operator indicated errors by setting the EV_ERROR flog in the flags field
+ * embedded in the knote's kevent structure - with the specific error indicated in the
+ * corresponding data field.
+ *
+ * The return value indicates if the knote should already be considered "activated" at
+ * the time of attach (one or more of the interest events has already occured).
+ *
+ * f_detach -
+ * called to disassociate the knote from the underlying object delivering events
+ * the filter should not attempt to deliver events through this knote after this
+ * operation returns control to the kq system.
+ *
+ * f_event -
+ * if the knote() function (or KNOTE() macro) is called against a list of knotes,
+ * this operator will be called on each knote in the list.
+ *
+ * The "hint" parameter is completely filter-specific, but usually indicates an
+ * event or set of events that have occured against the source object associated
+ * with the list.
+ *
+ * The return value indicates if the knote should already be considered "activated" at
+ * the time of attach (one or more of the interest events has already occured).
+ *
+ * f_process -
+ * called when attempting to deliver triggered events to user-space.
+ *
+ * If the knote was previously activated, this operator will be called when a
+ * thread is trying to deliver events to user-space. The filter gets one last
+ * chance to determine if the event/events are still interesting for this knote
+ * (are the conditions still right to deliver an event). If so, the filter
+ * fills in the output kevent structure with the information to be delivered.
+ *
+ * The input context/data parameter is used during event delivery. Some
+ * filters allow additional data delivery as part of event delivery. This
+ * context field indicates if space was made available for these additional
+ * items and how that space is to be allocated/carved-out.
+ *
+ * The filter may set EV_CLEAR or EV_ONESHOT in the output flags field to indicate
+ * special post-delivery dispositions for the knote.
+ *
+ * EV_CLEAR - indicates that all matching events have been delivered. Even
+ * though there were events to deliver now, there will not be any
+ * more until some additional events are delivered to the knote
+ * via the f_event operator, or the interest set is changed via
+ * the f_touch operator. The knote can remain deactivated after
+ * processing this event delivery.
+ *
+ * EV_ONESHOT - indicates that this is the last event to be delivered via
+ * this knote. It will automatically be deleted upon delivery
+ * (or if in dispatch-mode, upon re-enablement after this delivery).
+ *
+ * The return value indicates if the knote has delivered an output event.
+ * Unless one of the special output flags was set in the output kevent, a non-
+ * zero return value ALSO indicates that the knote should be re-activated
+ * for future event processing (in case it delivers level-based or a multi-edge
+ * type events like message queues that already exist).
+ *
+ * NOTE: In the future, the boolean may change to an enum that allows more
+ * explicit indication of just delivering a current event vs delivering
+ * an event with more events still pending.
+ *
+ * f_peek -
+ * For knotes marked KN_STAYACTIVE, indicate if the knote is truly active at
+ * the moment (not used for event delivery, but for status checks).
+ */