1 #ifndef _FDEVENT_H_
2 #define _FDEVENT_H_
3 
4 #ifdef HAVE_CONFIG_H
5 # include "config.h"
6 #endif
7 
8 #include "settings.h"
9 #include "bitset.h"
10 
11 #if defined HAVE_STDINT_H
12 # include <stdint.h>
13 #elif defined HAVE_INTTYPES_H
14 # include <inttypes.h>
15 #endif
16 
17 #include <sys/types.h>
18 
19 /* select event-system */
20 
21 #if defined(HAVE_EPOLL_CTL) && defined(HAVE_SYS_EPOLL_H)
22 # define USE_LINUX_EPOLL
23 #endif
24 
25 /* MacOS 10.3.x has poll.h under /usr/include/, all other unixes
26  * under /usr/include/sys/ */
27 #if defined HAVE_POLL && (defined(HAVE_SYS_POLL_H) || defined(HAVE_POLL_H))
28 # define USE_POLL
29 #endif
30 
31 #if defined HAVE_SELECT
32 # ifdef __WIN32
33 #  include <winsock2.h>
34 # endif
35 # define USE_SELECT
36 # ifdef HAVE_SYS_SELECT_H
37 #  include <sys/select.h>
38 # endif
39 #endif
40 
41 #if defined HAVE_SYS_DEVPOLL_H && defined(__sun)
42 # define USE_SOLARIS_DEVPOLL
43 #endif
44 
45 #if defined HAVE_PORT_H && defined HAVE_PORT_CREATE && defined(__sun)
46 # define USE_SOLARIS_PORT
47 # include <port.h>
48 #endif
49 
50 #if defined HAVE_SYS_EVENT_H && defined HAVE_KQUEUE
51 # define USE_FREEBSD_KQUEUE
52 #endif
53 
54 #if defined HAVE_LIBEV
55 # define USE_LIBEV
56 #endif
57 
58 struct server;
59 
60 typedef handler_t (*fdevent_handler)(struct server *srv, void *ctx, int revents);
61 
62 /* these are the POLL* values from <bits/poll.h> (linux poll)
63  */
64 
65 #define FDEVENT_IN     BV(0)
66 #define FDEVENT_PRI    BV(1)
67 #define FDEVENT_OUT    BV(2)
68 #define FDEVENT_ERR    BV(3)
69 #define FDEVENT_HUP    BV(4)
70 #define FDEVENT_NVAL   BV(5)
71 
72 typedef enum { FD_EVENT_TYPE_UNSET = -1,
73 		FD_EVENT_TYPE_CONNECTION,
74 		FD_EVENT_TYPE_FCGI_CONNECTION,
75 		FD_EVENT_TYPE_DIRWATCH,
76 		FD_EVENT_TYPE_CGI_CONNECTION
77 } fd_event_t;
78 
79 typedef enum { FDEVENT_HANDLER_UNSET,
80 		FDEVENT_HANDLER_SELECT,
81 		FDEVENT_HANDLER_POLL,
82 		FDEVENT_HANDLER_LINUX_SYSEPOLL,
83 		FDEVENT_HANDLER_SOLARIS_DEVPOLL,
84 		FDEVENT_HANDLER_SOLARIS_PORT,
85 		FDEVENT_HANDLER_FREEBSD_KQUEUE,
86 	        FDEVENT_HANDLER_LIBEV,
87 	        FDEVENT_HANDLER_LIBMTCP
88 } fdevent_handler_t;
89 
90 
91 typedef struct _fdnode {
92 	fdevent_handler handler;
93 	void *ctx;
94 	void *handler_ctx;
95 	int fd;
96 	int events;
97 } fdnode;
98 
99 /**
100  * array of unused fd's
101  *
102  */
103 
104 typedef struct {
105 	int *ptr;
106 
107 	size_t used;
108 	size_t size;
109 } buffer_int;
110 
111 /**
112  * fd-event handler for select(), poll() and rt-signals on Linux 2.4
113  *
114  */
115 typedef struct fdevents {
116 	struct server *srv;
117 	fdevent_handler_t type;
118 
119 	fdnode **fdarray;
120 	size_t maxfds;
121 
122 #ifdef USE_LINUX_EPOLL
123 	int epoll_fd;
124 	struct epoll_event *epoll_events;
125 #endif
126 
127 #ifdef HAVE_LIBMTCP
128 	struct mtcp_epoll_event *_epoll_events;
129 #endif
130 
131 #ifdef USE_POLL
132 	struct pollfd *pollfds;
133 
134 	size_t size;
135 	size_t used;
136 
137 	buffer_int unused;
138 #endif
139 #ifdef USE_SELECT
140 	fd_set select_read;
141 	fd_set select_write;
142 	fd_set select_error;
143 
144 	fd_set select_set_read;
145 	fd_set select_set_write;
146 	fd_set select_set_error;
147 
148 	int select_max_fd;
149 #endif
150 #ifdef USE_SOLARIS_DEVPOLL
151 	int devpoll_fd;
152 	struct pollfd *devpollfds;
153 #endif
154 #ifdef USE_SOLARIS_PORT
155 	port_event_t *port_events;
156 #endif
157 #ifdef USE_FREEBSD_KQUEUE
158 	int kq_fd;
159 	struct kevent *kq_results;
160 #endif
161 #ifdef USE_SOLARIS_PORT
162 	int port_fd;
163 #endif
164 #ifdef USE_LIBEV
165 	struct ev_loop *libev_loop;
166 #endif
167 	int (*reset)(struct fdevents *ev);
168 	void (*free)(struct fdevents *ev);
169 
170 	int (*event_set)(struct fdevents *ev, int fde_ndx, int fd, int events);
171 	int (*event_del)(struct fdevents *ev, int fde_ndx, int fd);
172 	int (*event_get_revent)(struct fdevents *ev, size_t ndx);
173 	int (*event_get_fd)(struct fdevents *ev, size_t ndx);
174 
175 	int (*event_next_fdndx)(struct fdevents *ev, int ndx);
176 
177 	int (*poll)(struct fdevents *ev, int timeout_ms);
178 
179 	int (*fcntl_set)(struct fdevents *ev, int fd);
180 } fdevents;
181 
182 fdevents *fdevent_init(struct server *srv, size_t maxfds, fdevent_handler_t type);
183 int fdevent_reset(fdevents *ev); /* "init" after fork() */
184 void fdevent_free(fdevents *ev);
185 
186 int fdevent_event_set(fdevents *ev, int *fde_ndx, int fd, int events); /* events can be FDEVENT_IN, FDEVENT_OUT or FDEVENT_IN | FDEVENT_OUT */
187 int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd);
188 int fdevent_event_get_revent(fdevents *ev, size_t ndx);
189 int fdevent_event_get_fd(fdevents *ev, size_t ndx);
190 fdevent_handler fdevent_get_handler(fdevents *ev, int fd);
191 void * fdevent_get_context(fdevents *ev, int fd);
192 
193 int fdevent_event_next_fdndx(fdevents *ev, int ndx);
194 
195 int fdevent_poll(fdevents *ev, int timeout_ms);
196 
197 int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx);
198 int fdevent_unregister(fdevents *ev, int fd);
199 
200 int fdevent_fcntl_set(fdevents *ev, int fd);
201 
202 int fdevent_select_init(fdevents *ev);
203 int fdevent_poll_init(fdevents *ev);
204 int fdevent_linux_sysepoll_init(fdevents *ev);
205 int fdevent_solaris_devpoll_init(fdevents *ev);
206 int fdevent_solaris_port_init(fdevents *ev);
207 int fdevent_freebsd_kqueue_init(fdevents *ev);
208 int fdevent_libev_init(fdevents *ev);
209 int fdevent_libmtcp_epoll_init(fdevents *ev);
210 
211 #endif
212