2 * Copyright (c) 2009 Mark Heily <mark@heily.com>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #ifndef _KQUEUE_PRIVATE_H
18 #define _KQUEUE_PRIVATE_H
20 #if defined (__SVR4) && defined (__sun)
23 /* Used to set portev_events for PORT_SOURCE_USER */
24 # define X_PORT_SOURCE_SIGNAL 101
25 # define X_PORT_SOURCE_USER 102
33 #include <sys/select.h>
34 #include "../../include/sys/event.h"
38 /* GCC atomic builtins.
39 * See: http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
43 # define atomic_inc atomic_inc_32
44 # define atomic_dec atomic_dec_32
46 # define atomic_inc(p) __sync_add_and_fetch((p), 1)
47 # define atomic_dec(p) __sync_sub_and_fetch((p), 1)
50 /* Maximum events returnable in a single kevent() call */
51 #define MAX_KEVENT 512
56 extern int KQUEUE_DEBUG;
58 #define dbg_puts(str) do { \
60 fprintf(stderr, "KQ: %s(): %s\n", __func__,str); \
63 #define dbg_printf(fmt,...) do { \
65 fprintf(stderr, "KQ: %s(): "fmt"\n", __func__,__VA_ARGS__); \
68 #define dbg_perror(str) do { \
70 fprintf(stderr, "KQ: %s(): %s: %s (errno=%d)\n", \
71 __func__, str, strerror(errno), errno); \
74 # define reset_errno() do { errno = 0; } while (0)
77 # define dbg_puts(str) ;
78 # define dbg_printf(fmt,...) ;
79 # define dbg_perror(str) ;
80 # define reset_errno() ;
89 * Flags used by knote->flags
91 #define KNFL_PASSIVE_SOCKET (0x01) /* Socket is in listen(2) mode */
93 /* TODO: Make this a variable length structure and allow
94 each filter to add custom fields at the end.
100 int pfd; /* Used by timerfd */
101 int events; /* Used by socket */
103 nlink_t nlink; /* Used by vnode */
104 off_t size; /* Used by vnode */
107 pthread_t tid; /* Used by posix/timer.c */
109 TAILQ_ENTRY(knote) event_ent; /* Used by filter->kf_event */
110 RB_ENTRY(knote) kntree_ent; /* Used by filter->kntree */
112 LIST_HEAD(knotelist, knote);
114 #define KNOTE_ENABLE(ent) do { \
115 (ent)->kev.flags &= ~EV_DISABLE; \
116 } while (0/*CONSTCOND*/)
118 #define KNOTE_DISABLE(ent) do { \
119 (ent)->kev.flags |= EV_DISABLE; \
120 } while (0/*CONSTCOND*/)
125 /* filter operations */
127 int (*kf_init)(struct filter *);
128 void (*kf_destroy)(struct filter *);
129 int (*kf_copyout)(struct filter *, struct kevent *, int);
131 /* knote operations */
133 int (*kn_create)(struct filter *, struct knote *);
134 int (*kn_modify)(struct filter *, struct knote *,
135 const struct kevent *);
136 int (*kn_delete)(struct filter *, struct knote *);
137 int (*kn_enable)(struct filter *, struct knote *);
138 int (*kn_disable)(struct filter *, struct knote *);
140 struct eventfd *kf_efd; /* Used by user.c */
141 int kf_pfd; /* fd to poll(2) for readiness */
142 int kf_wfd; /* fd to write when an event occurs */
144 struct evfilt_data *kf_data; /* filter-specific data */
145 RB_HEAD(knt, knote) kf_knote;
146 TAILQ_HEAD(, knote) kf_event; /* events that have occurred */
147 struct kqueue *kf_kqueue;
150 /* Use this to declare a filter that is not implemented */
151 #define EVFILT_NOTIMPL { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
155 struct filter kq_filt[EVFILT_SYSCOUNT];
156 fd_set kq_fds, kq_rfds;
158 pthread_mutex_t kq_mtx;
160 int kq_port; /* see: port_create(2) */
161 pthread_key_t kq_port_event;
163 volatile uint32_t kq_ref;
164 RB_ENTRY(kqueue) entries;
167 struct knote * knote_lookup(struct filter *, short);
168 struct knote * knote_lookup_data(struct filter *filt, intptr_t);
169 struct knote * knote_new(void);
170 void knote_free(struct filter *, struct knote *);
171 void knote_free_all(struct filter *);
172 void knote_insert(struct filter *, struct knote *);
173 int knote_get_socket_type(struct knote *);
175 /* TODO: these deal with the eventlist, should use a different prefix */
176 void knote_enqueue(struct filter *, struct knote *);
177 struct knote * knote_dequeue(struct filter *);
178 int knote_events_pending(struct filter *);
180 struct eventfd * eventfd_create(void);
181 void eventfd_free(struct eventfd *);
182 int eventfd_raise(struct eventfd *);
183 int eventfd_lower(struct eventfd *);
184 int eventfd_reader(struct eventfd *);
185 int eventfd_writer(struct eventfd *);
187 int filter_lookup(struct filter **, struct kqueue *, short);
188 int filter_socketpair(struct filter *);
189 int filter_register_all(struct kqueue *);
190 void filter_unregister_all(struct kqueue *);
191 const char *filter_name(short);
192 int filter_lower(struct filter *);
193 int filter_raise(struct filter *);
195 int kevent_wait(struct kqueue *, const struct timespec *);
196 int kevent_copyout(struct kqueue *, int, struct kevent *, int);
197 void kevent_free(struct kqueue *);
198 const char *kevent_dump(const struct kevent *);
200 struct kqueue * kqueue_get(int);
201 void kqueue_put(struct kqueue *);
202 #define kqueue_lock(kq) pthread_mutex_lock(&(kq)->kq_mtx)
203 #define kqueue_unlock(kq) pthread_mutex_unlock(&(kq)->kq_mtx)
204 int kqueue_validate(struct kqueue *);
206 #endif /* ! _KQUEUE_PRIVATE_H */