xref: /dragonfly/sys/sys/event.h (revision 0d47c594fde0de2008b2f26db9ab7a6a22eaf64f)
1 /*-
2  * Copyright (c) 1999,2000,2001 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  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
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: src/sys/sys/event.h,v 1.5.2.6 2003/02/09 15:28:13 nectar Exp $
27  */
28 
29 #ifndef _SYS_EVENT_H_
30 #define _SYS_EVENT_H_
31 
32 #ifndef _SYS_TYPES_H_
33 #include <sys/types.h>
34 #endif
35 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
36 #include <sys/queue.h>
37 #endif
38 
39 #define EVFILT_READ           (-1)
40 #define EVFILT_WRITE                    (-2)
41 #define EVFILT_AIO            (-3)      /* attached to aio requests */
42 #define EVFILT_VNODE                    (-4)      /* attached to vnodes */
43 #define EVFILT_PROC           (-5)      /* attached to struct proc */
44 #define EVFILT_SIGNAL                   (-6)      /* attached to struct proc */
45 #define EVFILT_TIMER                    (-7)      /* timers */
46 #define EVFILT_EXCEPT                   (-8)      /* exceptional conditions */
47 #define EVFILT_USER           (-9)      /* user events */
48 #define EVFILT_FS             (-10)     /* filesystem events */
49 
50 #define EVFILT_MARKER                   0xF       /* placemarker for tailq */
51 
52 #define EVFILT_SYSCOUNT                 10
53 
54 #define EV_SET(kevp_, a, b, c, d, e, f) do {      \
55           struct kevent *kevp = (kevp_);                    \
56           (kevp)->ident = (a);                              \
57           (kevp)->filter = (b);                             \
58           (kevp)->flags = (c);                              \
59           (kevp)->fflags = (d);                             \
60           (kevp)->data = (e);                     \
61           (kevp)->udata = (f);                              \
62 } while(0)
63 
64 struct kevent {
65           uintptr_t ident;              /* identifier for this event */
66           short               filter;             /* filter for event */
67           u_short             flags;
68           u_int               fflags;
69           intptr_t  data;
70           void                *udata;             /* opaque user data identifier */
71 };
72 
73 /* actions */
74 #define EV_ADD                0x0001              /* add event to kq (implies enable) */
75 #define EV_DELETE   0x0002              /* delete event from kq */
76 #define EV_ENABLE   0x0004              /* enable event */
77 #define EV_DISABLE  0x0008              /* disable event (not reported) */
78 
79 /* flags */
80 #define EV_ONESHOT  0x0010              /* only report one occurrence */
81 #define EV_CLEAR    0x0020              /* clear event state after reporting */
82 #define EV_RECEIPT  0x0040              /* force EV_ERROR on success, data=0 */
83 #define EV_DISPATCH 0x0080              /* disable event after reporting */
84 
85 #define EV_SYSFLAGS 0xF800              /* reserved by system */
86 #define EV_FLAG1    0x2000              /* filter-specific flag */
87 
88 /* returned values */
89 #define EV_HUP                0x0800              /* complete peer disconnect */
90 #define EV_EOF                0x8000              /* EOF detected */
91 #define EV_ERROR    0x4000              /* error, data contains errno */
92 #define EV_NODATA   0x1000              /* EOF and no more data */
93 
94 /*
95  * EVFILT_USER
96  */
97  /*
98   * data/hint flags/masks for EVFILT_USER, shared with userspace
99   *
100   * On input, the top two bits of fflags specifies how the lower twenty four
101   * bits should be applied to the stored value of fflags.
102   *
103   * On output, the top two bits will always be set to NOTE_FFNOP and the
104   * remaining twenty four bits will contain the stored fflags value.
105   */
106 #define NOTE_FFNOP      0x00000000      /* ignore input fflags */
107 #define NOTE_FFAND      0x40000000      /* AND fflags */
108 #define NOTE_FFOR       0x80000000      /* OR fflags */
109 #define NOTE_FFCOPY     0xc0000000      /* copy fflags */
110 #define NOTE_FFCTRLMASK 0xc0000000      /* masks for operations */
111 #define NOTE_FFLAGSMASK 0x00ffffff
112 
113 #define NOTE_TRIGGER    0x01000000      /* trigger for output */
114 
115 /*
116  * data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
117  */
118 #define NOTE_LOWAT  0x0001                        /* low water mark */
119 
120 /*
121  * data/hint flags for EVFILT_EXCEPT, shared with userspace and with
122  * EVFILT_{READ|WRITE}
123  */
124 #define NOTE_OOB    0x0002                        /* OOB data on a socket */
125 
126 /*
127  * data/hint flags for EVFILT_VNODE, shared with userspace
128  */
129 #define   NOTE_DELETE         0x0001                        /* vnode was removed */
130 #define   NOTE_WRITE          0x0002                        /* data contents changed */
131 #define   NOTE_EXTEND         0x0004                        /* size increased */
132 #define   NOTE_ATTRIB         0x0008                        /* attributes changed */
133 #define   NOTE_LINK 0x0010                        /* link count changed */
134 #define   NOTE_RENAME         0x0020                        /* vnode was renamed */
135 #define   NOTE_REVOKE         0x0040                        /* vnode access was revoked */
136 
137 /*
138  * data/hint flags for EVFILT_PROC, shared with userspace
139  */
140 #define   NOTE_EXIT 0x80000000                    /* process exited */
141 #define   NOTE_FORK 0x40000000                    /* process forked */
142 #define   NOTE_EXEC 0x20000000                    /* process exec'd */
143 #define   NOTE_PCTRLMASK      0xf0000000                    /* mask for hint bits */
144 #define   NOTE_PDATAMASK      0x000fffff                    /* mask for pid */
145 
146 /* additional flags for EVFILT_PROC */
147 #define   NOTE_TRACK          0x00000001                    /* follow across forks */
148 #define   NOTE_TRACKERR       0x00000002                    /* could not track child */
149 #define   NOTE_CHILD          0x00000004                    /* am a child process */
150 
151 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
152 
153 struct knote;
154 SLIST_HEAD(klist, knote);
155 
156 /*
157  * Used to maintain information about processes that wish to be
158  * notified when I/O becomes possible.
159  */
160 struct kqinfo {
161           struct    klist ki_note;                /* kernel note list */
162 };
163 
164 #endif
165 
166 #ifdef _KERNEL
167 
168 #define KNOTE(list, hint)     if (!SLIST_EMPTY((list))) knote(list, hint)
169 
170 /*
171  * Flag indicating hint is a signal.  Used by EVFILT_SIGNAL, and also
172  * shared by EVFILT_PROC  (all knotes attached to p->p_klist)
173  *
174  * NOTE_OLDAPI - Indicate that standard filters are being called from the
175  *                   select/poll wrapper.
176  *
177  * NOTE_HUPONLY - Indicate that an EVFILT_READ should not trigger on
178  *                    read data present, only on a HUP/EOF.  Used by kernel
179  *                    poll() handler.
180  */
181 #define NOTE_SIGNAL 0x08000000
182 #define NOTE_OLDAPI 0x04000000          /* select/poll note */
183 #define NOTE_HUPONLY          0x02000000          /* select/poll note */
184 
185 #define FILTEROP_ISFD         0x0001              /* if ident == filedescriptor */
186 #define FILTEROP_MPSAFE       0x0002
187 
188 struct filterops {
189           u_short   f_flags;
190 
191           /* f_attach returns 0 on success or valid error code on failure */
192           int       (*f_attach)         (struct knote *kn);
193           void      (*f_detach)         (struct knote *kn);
194 
195         /* f_event returns boolean truth */
196           int       (*f_event)          (struct knote *kn, long hint);
197 };
198 
199 struct knote {
200           SLIST_ENTRY(knote)  kn_link;  /* for fd */
201           TAILQ_ENTRY(knote)  kn_kqlink;          /* for kq_knlist */
202           SLIST_ENTRY(knote)  kn_next;  /* for struct kqinfo */
203           TAILQ_ENTRY(knote)  kn_tqe;             /* for kq_knpend */
204           struct                        kqueue *kn_kq;      /* which queue we are on */
205           struct                        kevent kn_kevent;
206           int                           kn_status;
207           int                           kn_sfflags;         /* saved filter flags */
208           int                           kn_uniqifier;       /* distinguish similar notes */
209           int                           kn_unused01;
210           intptr_t            kn_sdata; /* saved data field */
211           union {
212                     struct              file *p_fp;         /* file data pointer */
213                     struct              proc *p_proc;       /* proc pointer */
214                     int                 hookid;
215           } kn_ptr;
216           struct                        filterops *kn_fop;
217           caddr_t                       kn_hook;
218 };
219 
220 #define KN_ACTIVE   0x0001                        /* event has been triggered */
221 #define KN_QUEUED   0x0002                        /* event is on queue */
222 #define KN_DISABLED 0x0004                        /* event is disabled */
223 #define KN_DETACHED 0x0008                        /* knote is detached */
224 #define KN_REPROCESS          0x0010                        /* force reprocessing race */
225 #define KN_DELETING 0x0020                        /* deletion in progress */
226 #define KN_PROCESSING         0x0040                        /* event processing in prog */
227 #define KN_WAITING  0x0080                        /* waiting on processing */
228 
229 #define kn_id                 kn_kevent.ident
230 #define kn_filter   kn_kevent.filter
231 #define kn_flags    kn_kevent.flags
232 #define kn_fflags   kn_kevent.fflags
233 #define kn_data               kn_kevent.data
234 #define kn_fp                 kn_ptr.p_fp
235 
236 struct proc;
237 struct thread;
238 struct filedesc;
239 struct kevent_args;
240 
241 #define KEVENT_TIMEOUT_PRECISE                    0x01
242 #define KEVENT_AUTO_STALE               0x02      /* used by poll/select */
243 #define KEVENT_UNIQUE_NOTES             0x04      /* force unique notes */
244 
245 #define KEVENT_SCAN_MASK                0xF0
246 #define KEVENT_SCAN_KEEP_MARKER                   0x10
247 #define KEVENT_SCAN_RELOAD_MARKER       0x20
248 #define KEVENT_SCAN_INSERT_MARKER       0x40
249 
250 typedef int         (*k_copyout_fn)(void *arg, struct kevent *kevp, int count,
251     int *res);
252 typedef int         (*k_copyin_fn)(void *arg, struct kevent *kevp, int max,
253     int *events);
254 int kern_kevent(struct kqueue *kq, int nevents, int *res, void *uap,
255     k_copyin_fn kevent_copyin, k_copyout_fn kevent_copyout,
256     struct timespec *tsp, int flags);
257 
258 void      knote(struct klist *, long);
259 void      knote_insert(struct klist *, struct knote *);
260 void      knote_remove(struct klist *, struct knote *);
261 void      knote_assume_knotes(struct kqinfo *, struct kqinfo *,
262               struct filterops *, void *);
263 void      knote_fdclose(struct file *, struct filedesc *, int);
264 void      kqueue_init(struct kqueue *, struct filedesc *);
265 void      kqueue_terminate(struct kqueue *);
266 int       kqueue_register(struct kqueue *, struct kevent *, int *, int);
267 
268 extern struct klist fs_klist; /* EVFILT_FS */
269 
270 #endif    /* _KERNEL */
271 
272 #if !defined(_KERNEL) || defined(_KERNEL_VIRTUAL)
273 
274 #include <sys/cdefs.h>
275 struct timespec;
276 
277 __BEGIN_DECLS
278 int     kqueue (void);
279 int     kevent (int, const struct kevent *, int, struct kevent *,
280                     int, const struct timespec *);
281 __END_DECLS
282 #endif /* !_KERNEL */
283 
284 #endif /* !_SYS_EVENT_H_ */
285