summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2004-07-14 07:02:03 +0000
committeralfred <alfred@FreeBSD.org>2004-07-14 07:02:03 +0000
commit9f832c00ba2aa24eade0b2ef01b987cd24e8c55b (patch)
treecb2d9121acd71de4c8a917a1d42a3c89af1a052c /sys
parent29fd908e9d3e8beb66f8a8f4c43c3980daddf763 (diff)
downloadFreeBSD-src-9f832c00ba2aa24eade0b2ef01b987cd24e8c55b.zip
FreeBSD-src-9f832c00ba2aa24eade0b2ef01b987cd24e8c55b.tar.gz
Make FIOASYNC, FIOSETOWN and FIOGETOWN work on kqueues.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_event.c31
-rw-r--r--sys/sys/eventvar.h4
2 files changed, 32 insertions, 3 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index bd0e6d9..4b9a751 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -33,10 +33,11 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
-#include <sys/malloc.h>
+#include <sys/malloc.h>
#include <sys/unistd.h>
#include <sys/file.h>
#include <sys/filedesc.h>
+#include <sys/filio.h>
#include <sys/fcntl.h>
#include <sys/selinfo.h>
#include <sys/queue.h>
@@ -44,6 +45,8 @@ __FBSDID("$FreeBSD$");
#include <sys/eventvar.h>
#include <sys/poll.h>
#include <sys/protosw.h>
+#include <sys/sigio.h>
+#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/stat.h>
@@ -811,9 +814,29 @@ kqueue_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
/*ARGSUSED*/
static int
-kqueue_ioctl(struct file *fp, u_long com, void *data,
+kqueue_ioctl(struct file *fp, u_long cmd, void *data,
struct ucred *active_cred, struct thread *td)
{
+ struct kqueue *kq;
+
+ kq = fp->f_data;
+ switch (cmd) {
+ case FIOASYNC:
+ if (*(int *)data) {
+ kq->kq_state |= KQ_ASYNC;
+ } else {
+ kq->kq_state &= ~KQ_ASYNC;
+ }
+ return (0);
+
+ case FIOSETOWN:
+ return (fsetown(*(int *)data, &kq->kq_sigio));
+
+ case FIOGETOWN:
+ *(int *)data = fgetown(&kq->kq_sigio);
+ return (0);
+ }
+
return (ENOTTY);
}
@@ -910,6 +933,7 @@ kqueue_close(struct file *fp, struct thread *td)
kq->kq_state &= ~KQ_SEL;
selwakeuppri(&kq->kq_sel, PSOCK);
}
+ funsetown(&kq->kq_sigio);
free(kq, M_KQUEUE);
fp->f_data = NULL;
@@ -928,6 +952,9 @@ kqueue_wakeup(struct kqueue *kq)
kq->kq_state &= ~KQ_SEL;
selwakeuppri(&kq->kq_sel, PSOCK);
}
+ if (kq->kq_state & KQ_ASYNC) {
+ pgsigio(&kq->kq_sigio, SIGIO, 0);
+ }
KNOTE(&kq->kq_sel.si_note, 0);
}
diff --git a/sys/sys/eventvar.h b/sys/sys/eventvar.h
index 3701d44..ef9087b 100644
--- a/sys/sys/eventvar.h
+++ b/sys/sys/eventvar.h
@@ -35,11 +35,13 @@
struct kqueue {
TAILQ_HEAD(kqlist, knote) kq_head; /* list of pending event */
int kq_count; /* number of pending events */
- struct selinfo kq_sel;
+ struct selinfo kq_sel;
+ struct sigio *kq_sigio;
struct filedesc *kq_fdp;
int kq_state;
#define KQ_SEL 0x01
#define KQ_SLEEP 0x02
+#define KQ_ASYNC 0x04
struct kevent kq_kev[KQ_NEVENTS];
};
OpenPOWER on IntegriCloud