Tizen 2.1 base
[platform/upstream/gcd.git] / kqueue-1.0.4 / src / common / private.h
1 /*
2  * Copyright (c) 2009 Mark Heily <mark@heily.com>
3  *
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.
7  *
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.
15  */
16
17 #ifndef  _KQUEUE_PRIVATE_H
18 #define  _KQUEUE_PRIVATE_H
19
20 #if defined (__SVR4) && defined (__sun)
21 # define SOLARIS
22 # include <port.h>
23   /* Used to set portev_events for PORT_SOURCE_USER */
24 # define X_PORT_SOURCE_SIGNAL  101
25 # define X_PORT_SOURCE_USER    102
26 #endif
27
28 #include <errno.h>
29 #include <pthread.h>
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <sys/select.h>
34 #include "../../include/sys/event.h"
35
36 #include "tree.h"
37
38 /* GCC atomic builtins. 
39  * See: http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html 
40  */
41 #ifdef __sun
42 # include <atomic.h>
43 # define atomic_inc      atomic_inc_32
44 # define atomic_dec      atomic_dec_32
45 #else
46 # define atomic_inc(p)   __sync_add_and_fetch((p), 1)
47 # define atomic_dec(p)   __sync_sub_and_fetch((p), 1)
48 #endif
49
50 /* Maximum events returnable in a single kevent() call */
51 #define MAX_KEVENT  512
52
53
54 #ifndef NDEBUG
55
56 extern int KQUEUE_DEBUG;
57
58 #define dbg_puts(str)           do {                                \
59     if (KQUEUE_DEBUG)                                               \
60       fprintf(stderr, "KQ: %s(): %s\n", __func__,str);              \
61 } while (0)
62
63 #define dbg_printf(fmt,...)     do {                                \
64     if (KQUEUE_DEBUG)                                               \
65       fprintf(stderr, "KQ: %s(): "fmt"\n", __func__,__VA_ARGS__);   \
66 } while (0)
67
68 #define dbg_perror(str)         do {                                \
69     if (KQUEUE_DEBUG)                                               \
70       fprintf(stderr, "KQ: %s(): %s: %s (errno=%d)\n",              \
71               __func__, str, strerror(errno), errno);               \
72 } while (0)
73
74 # define reset_errno()          do { errno = 0; } while (0)
75
76 #else /* NDEBUG */
77 # define dbg_puts(str)           ;
78 # define dbg_printf(fmt,...)     ;
79 # define dbg_perror(str)         ;
80 # define reset_errno()           ;
81 #endif 
82
83
84 struct kqueue;
85 struct kevent;
86 struct evfilt_data;
87
88 /* 
89  * Flags used by knote->flags
90  */
91 #define KNFL_PASSIVE_SOCKET  (0x01)  /* Socket is in listen(2) mode */
92
93 /* TODO: Make this a variable length structure and allow
94    each filter to add custom fields at the end.
95  */
96 struct knote {
97     struct kevent     kev;
98     int               flags;       
99     union {
100         int           pfd;       /* Used by timerfd */
101         int           events;    /* Used by socket */
102         struct {
103             nlink_t   nlink;  /* Used by vnode */
104             off_t     size;   /* Used by vnode */
105         } vnode;
106         timer_t       timerid;  
107         pthread_t     tid;          /* Used by posix/timer.c */
108     } data;
109     TAILQ_ENTRY(knote) event_ent;    /* Used by filter->kf_event */
110     RB_ENTRY(knote)   kntree_ent;   /* Used by filter->kntree */
111 };
112 LIST_HEAD(knotelist, knote);
113
114 #define KNOTE_ENABLE(ent)           do {                            \
115             (ent)->kev.flags &= ~EV_DISABLE;                        \
116 } while (0/*CONSTCOND*/)
117
118 #define KNOTE_DISABLE(ent)          do {                            \
119             (ent)->kev.flags |=  EV_DISABLE;                        \
120 } while (0/*CONSTCOND*/)
121
122 struct filter {
123     short     kf_id;
124
125     /* filter operations */
126
127     int     (*kf_init)(struct filter *);
128     void    (*kf_destroy)(struct filter *);
129     int     (*kf_copyout)(struct filter *, struct kevent *, int);
130
131     /* knote operations */
132
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 *);
139
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 */
143     sigset_t            kf_sigmask;
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;
148 };
149
150 /* Use this to declare a filter that is not implemented */
151 #define EVFILT_NOTIMPL { 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
152
153 struct kqueue {
154     int             kq_sockfd[2];
155     struct filter   kq_filt[EVFILT_SYSCOUNT];
156     fd_set          kq_fds, kq_rfds; 
157     int             kq_nfds;
158     pthread_mutex_t kq_mtx;
159 #ifdef __sun__
160     int             kq_port;            /* see: port_create(2) */
161     pthread_key_t   kq_port_event;
162 #endif
163     volatile uint32_t        kq_ref;
164     RB_ENTRY(kqueue) entries;
165 };
166
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 *);
174
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 *);
179
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 *);
186
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 *);
194
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 *);
199
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 *);
205
206 #endif  /* ! _KQUEUE_PRIVATE_H */