Page MenuHomeFreeBSD

D48206.diff
No OneTemporary

D48206.diff

diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1398,10 +1398,11 @@
}
int
-kqueue_add_filteropts(int filt, const struct filterops *filtops)
+kqueue_assign_filteropts(int *filtp, struct filterops *filtops)
{
- int error;
+ int error, filt, i;
+ filt = *filtp;
error = 0;
if (filt > 0 || filt + EVFILT_SYSCOUNT < 0) {
printf(
@@ -1410,10 +1411,19 @@
return EINVAL;
}
mtx_lock(&filterops_lock);
- if (sysfilt_ops[~filt].for_fop != &null_filtops &&
+ if (filt == NO_EVFILT) {
+ for (i = EVFILT_USER_START; ~i < EVFILT_SYSCOUNT; i--)
+ if (sysfilt_ops[~i].for_fop == &null_filtops ||
+ sysfilt_ops[~i].for_fop == NULL)
+ break;
+ if (~i == EVFILT_SYSCOUNT)
+ error = ENFILE;
+ else
+ filt = i; /* record the index */
+ } else if (sysfilt_ops[~filt].for_fop != &null_filtops &&
sysfilt_ops[~filt].for_fop != NULL)
error = EEXIST;
- else {
+ if (error == 0) {
sysfilt_ops[~filt].for_fop = filtops;
sysfilt_ops[~filt].for_refcnt = 0;
}
@@ -1422,6 +1432,15 @@
return (error);
}
+int
+kqueue_add_filteropts(int filt, struct filterops *filtops)
+{
+ if (filt == NO_EVFILT)
+ return (EINVAL);
+
+ return kqueue_assign_filteropts(&filt, filtops);
+}
+
int
kqueue_del_filteropts(int filt)
{
@@ -2829,3 +2848,41 @@
fdrop(fp, td);
return (error);
}
+
+int
+kevent_module_handler(struct module *mod, int what, void *arg)
+{
+ struct kevent_module_data *data = arg;
+ modspecific_t ms;
+ int error;
+
+ switch (what) {
+ case MOD_LOAD:
+ if (data->offset != NO_EVFILT &&
+ data->offset > EVFILT_USER_START) {
+ if (bootverbose)
+ printf("%s: Invalid slot %d\n", __func__,
+ data->offset);
+ return (EINVAL);
+ }
+ error = kqueue_assign_filteropts(&data->offset, data->filt_ops);
+ if (error) {
+ data->offset = NO_EVFILT;
+ return (error);
+ }
+ ms.intval = data->offset;
+ MOD_XLOCK;
+ module_setspecific(mod, &ms);
+ MOD_XUNLOCK;
+ return (error);
+ case MOD_UNLOAD:
+ if (data->offset == NO_EVFILT)
+ return (0);
+ error = kqueue_del_filteropts(data->offset);
+ return (error);
+ default:
+ break;
+ }
+
+ return (EOPNOTSUPP);
+}
diff --git a/sys/sys/event.h b/sys/sys/event.h
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -45,7 +45,9 @@
#define EVFILT_USER (-11) /* User events */
#define EVFILT_SENDFILE (-12) /* attached to sendfile requests */
#define EVFILT_EMPTY (-13) /* empty send socket buf */
-#define EVFILT_SYSCOUNT 13
+#define EVFILT_SYSCOUNT 32
+#define NO_EVFILT (0) /* request for dynamic registration */
+#define EVFILT_USER_START (-17) /* User defined slots start */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define EV_SET(kevp_, a, b, c, d, e, f) do { \
@@ -322,12 +324,31 @@
size_t kevent_size;
};
+struct kevent_module_data {
+ const char *name; /* name of kernel event */
+ int offset; /* offset */
+ struct filterops *filt_ops; /* defined filtops */
+};
+
struct thread;
struct proc;
struct knlist;
+struct module;
struct mtx;
struct rwlock;
+#define KEVENT_MODULE(name, offset, new_filtops) \
+ static struct kevent_module_data name##_kevent_mod = { \
+ "kevent/" #name, offset, new_filtops \
+ }; \
+ static moduledata_t name##_mod = { \
+ "kevent/" #name, \
+ kevent_module_handler, \
+ &name##_kevent_mod \
+ }; \
+ DECLARE_MODULE(name, name##_mod, SI_SUB_SYSCALLS, SI_ORDER_MIDDLE)
+
+int kevent_module_handler(struct module *mod, int what, void *arg);
void knote(struct knlist *list, long hint, int lockflags);
void knote_fork(struct knlist *list, int pid);
struct knlist *knlist_alloc(struct mtx *lock);
@@ -349,6 +370,7 @@
int kqfd_register(int fd, struct kevent *kev, struct thread *p,
int mflag);
int kqueue_add_filteropts(int filt, const struct filterops *filtops);
+int kqueue_assign_filteropts(int *filtp, struct filterops *filtops);
int kqueue_del_filteropts(int filt);
void kqueue_drain_schedtask(void);

File Metadata

Mime Type
text/plain
Expires
Fri, May 22, 8:46 PM (15 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33430429
Default Alt Text
D48206.diff (4 KB)

Event Timeline