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 --- |