Deleted Added
full compact
kern_event.c (71500) kern_event.c (72521)
1/*-
2 * Copyright (c) 1999,2000 Jonathan Lemon <jlemon@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1999,2000 Jonathan Lemon <jlemon@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/kern/kern_event.c 71500 2001-01-24 00:35:12Z jhb $
26 * $FreeBSD: head/sys/kern/kern_event.c 72521 2001-02-15 16:34:11Z jlemon $
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/kernel.h>
32#include <sys/proc.h>
33#include <sys/malloc.h>
34#include <sys/unistd.h>

--- 8 unchanged lines hidden (view full) ---

43#include <sys/socket.h>
44#include <sys/socketvar.h>
45#include <sys/stat.h>
46#include <sys/sysproto.h>
47#include <sys/uio.h>
48
49#include <vm/vm_zone.h>
50
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/kernel.h>
32#include <sys/proc.h>
33#include <sys/malloc.h>
34#include <sys/unistd.h>

--- 8 unchanged lines hidden (view full) ---

43#include <sys/socket.h>
44#include <sys/socketvar.h>
45#include <sys/stat.h>
46#include <sys/sysproto.h>
47#include <sys/uio.h>
48
49#include <vm/vm_zone.h>
50
51static int filt_nullattach(struct knote *kn);
52static int filt_rwtypattach(struct knote *kn);
53static int filt_kqattach(struct knote *kn);
54static void filt_kqdetach(struct knote *kn);
55static int filt_kqueue(struct knote *kn, long hint);
56static int filt_procattach(struct knote *kn);
57static void filt_procdetach(struct knote *kn);
58static int filt_proc(struct knote *kn, long hint);
59
60static int kqueue_scan(struct file *fp, int maxevents,
61 struct kevent *ulistp, const struct timespec *timeout,
62 struct proc *p);
63static int kqueue_read(struct file *fp, struct uio *uio,
64 struct ucred *cred, int flags, struct proc *p);
65static int kqueue_write(struct file *fp, struct uio *uio,
66 struct ucred *cred, int flags, struct proc *p);
67static int kqueue_ioctl(struct file *fp, u_long com, caddr_t data,
68 struct proc *p);
69static int kqueue_poll(struct file *fp, int events, struct ucred *cred,
70 struct proc *p);
51static int kqueue_scan(struct file *fp, int maxevents,
52 struct kevent *ulistp, const struct timespec *timeout,
53 struct proc *p);
54static int kqueue_read(struct file *fp, struct uio *uio,
55 struct ucred *cred, int flags, struct proc *p);
56static int kqueue_write(struct file *fp, struct uio *uio,
57 struct ucred *cred, int flags, struct proc *p);
58static int kqueue_ioctl(struct file *fp, u_long com, caddr_t data,
59 struct proc *p);
60static int kqueue_poll(struct file *fp, int events, struct ucred *cred,
61 struct proc *p);
62static int kqueue_kqfilter(struct file *fp, struct knote *kn);
71static int kqueue_stat(struct file *fp, struct stat *st, struct proc *p);
72static int kqueue_close(struct file *fp, struct proc *p);
73static void kqueue_wakeup(struct kqueue *kq);
74
63static int kqueue_stat(struct file *fp, struct stat *st, struct proc *p);
64static int kqueue_close(struct file *fp, struct proc *p);
65static void kqueue_wakeup(struct kqueue *kq);
66
67static struct fileops kqueueops = {
68 kqueue_read,
69 kqueue_write,
70 kqueue_ioctl,
71 kqueue_poll,
72 kqueue_kqfilter,
73 kqueue_stat,
74 kqueue_close
75};
76
75static void knote_attach(struct knote *kn, struct filedesc *fdp);
76static void knote_drop(struct knote *kn, struct proc *p);
77static void knote_enqueue(struct knote *kn);
78static void knote_dequeue(struct knote *kn);
79static void knote_init(void);
80static struct knote *knote_alloc(void);
81static void knote_free(struct knote *kn);
82
77static void knote_attach(struct knote *kn, struct filedesc *fdp);
78static void knote_drop(struct knote *kn, struct proc *p);
79static void knote_enqueue(struct knote *kn);
80static void knote_dequeue(struct knote *kn);
81static void knote_init(void);
82static struct knote *knote_alloc(void);
83static void knote_free(struct knote *kn);
84
85static void filt_kqdetach(struct knote *kn);
86static int filt_kqueue(struct knote *kn, long hint);
87static int filt_procattach(struct knote *kn);
88static void filt_procdetach(struct knote *kn);
89static int filt_proc(struct knote *kn, long hint);
90static int filt_fileattach(struct knote *kn);
91
92static struct filterops kqread_filtops =
93 { 1, NULL, filt_kqdetach, filt_kqueue };
94static struct filterops proc_filtops =
95 { 0, filt_procattach, filt_procdetach, filt_proc };
96static struct filterops file_filtops =
97 { 1, filt_fileattach, NULL, NULL };
98
83static vm_zone_t knote_zone;
84
85#define KNOTE_ACTIVATE(kn) do { \
86 kn->kn_status |= KN_ACTIVE; \
87 if ((kn->kn_status & (KN_QUEUED | KN_DISABLED)) == 0) \
88 knote_enqueue(kn); \
89} while(0)
90
91#define KN_HASHSIZE 64 /* XXX should be tunable */
92#define KN_HASH(val, mask) (((val) ^ (val >> 8)) & (mask))
93
99static vm_zone_t knote_zone;
100
101#define KNOTE_ACTIVATE(kn) do { \
102 kn->kn_status |= KN_ACTIVE; \
103 if ((kn->kn_status & (KN_QUEUED | KN_DISABLED)) == 0) \
104 knote_enqueue(kn); \
105} while(0)
106
107#define KN_HASHSIZE 64 /* XXX should be tunable */
108#define KN_HASH(val, mask) (((val) ^ (val >> 8)) & (mask))
109
94static struct fileops kqueueops = {
95 kqueue_read,
96 kqueue_write,
97 kqueue_ioctl,
98 kqueue_poll,
99 kqueue_stat,
100 kqueue_close
101};
102
103extern struct filterops so_rwfiltops[];
104extern struct filterops fifo_rwfiltops[];
105extern struct filterops pipe_rwfiltops[];
106extern struct filterops vn_rwfiltops[];
107
108static struct filterops kq_rwfiltops[] = {
109 { 1, filt_kqattach, filt_kqdetach, filt_kqueue },
110 { 1, filt_nullattach, NULL, NULL },
111};
112
113extern struct filterops aio_filtops;
114extern struct filterops sig_filtops;
110extern struct filterops aio_filtops;
111extern struct filterops sig_filtops;
115extern struct filterops vn_filtops;
116
112
117static struct filterops rwtype_filtops =
118 { 1, filt_rwtypattach, NULL, NULL };
119static struct filterops proc_filtops =
120 { 0, filt_procattach, filt_procdetach, filt_proc };
121
122/*
113/*
123 * XXX
124 * These must match the order of defines in <sys/file.h>
114 * Table for for all system-defined filters.
125 */
115 */
126static struct filterops *rwtypfilt_sw[] = {
127 NULL, /* 0 */
128 vn_rwfiltops, /* DTYPE_VNODE */
129 so_rwfiltops, /* DTYPE_SOCKET */
130 pipe_rwfiltops, /* DTYPE_PIPE */
131 fifo_rwfiltops, /* DTYPE_FIFO */
132 kq_rwfiltops, /* DTYPE_KQUEUE */
133};
134
135/*
136 * table for for all system-defined filters.
137 */
138static struct filterops *sysfilt_ops[] = {
116static struct filterops *sysfilt_ops[] = {
139 &rwtype_filtops, /* EVFILT_READ */
140 &rwtype_filtops, /* EVFILT_WRITE */
117 &file_filtops, /* EVFILT_READ */
118 &file_filtops, /* EVFILT_WRITE */
141 &aio_filtops, /* EVFILT_AIO */
119 &aio_filtops, /* EVFILT_AIO */
142 &vn_filtops, /* EVFILT_VNODE */
120 &file_filtops, /* EVFILT_VNODE */
143 &proc_filtops, /* EVFILT_PROC */
144 &sig_filtops, /* EVFILT_SIGNAL */
145};
146
147static int
121 &proc_filtops, /* EVFILT_PROC */
122 &sig_filtops, /* EVFILT_SIGNAL */
123};
124
125static int
148filt_nullattach(struct knote *kn)
126filt_fileattach(struct knote *kn)
149{
127{
150 return (ENXIO);
128
129 return (fo_kqfilter(kn->kn_fp, kn));
151}
152
130}
131
153/*
154 * file-type specific attach routine for read/write filters
155 */
132/*ARGSUSED*/
156static int
133static int
157filt_rwtypattach(struct knote *kn)
134kqueue_kqfilter(struct file *fp, struct knote *kn)
158{
135{
159 struct filterops *fops;
160
161 fops = rwtypfilt_sw[kn->kn_fp->f_type];
162 if (fops == NULL)
163 return (EINVAL);
164 kn->kn_fop = &fops[~kn->kn_filter]; /* convert to 0-base index */
165 return (kn->kn_fop->f_attach(kn));
166}
167
168static int
169filt_kqattach(struct knote *kn)
170{
171 struct kqueue *kq = (struct kqueue *)kn->kn_fp->f_data;
172
136 struct kqueue *kq = (struct kqueue *)kn->kn_fp->f_data;
137
138 if (kn->kn_filter != EVFILT_READ)
139 return (1);
140
141 kn->kn_fop = &kqread_filtops;
173 SLIST_INSERT_HEAD(&kq->kq_sel.si_note, kn, kn_selnext);
174 return (0);
175}
176
177static void
178filt_kqdetach(struct knote *kn)
179{
180 struct kqueue *kq = (struct kqueue *)kn->kn_fp->f_data;

--- 747 unchanged lines hidden ---
142 SLIST_INSERT_HEAD(&kq->kq_sel.si_note, kn, kn_selnext);
143 return (0);
144}
145
146static void
147filt_kqdetach(struct knote *kn)
148{
149 struct kqueue *kq = (struct kqueue *)kn->kn_fp->f_data;

--- 747 unchanged lines hidden ---