- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)
1 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,1393 +0,0 @@ |
1 |
-/* |
|
2 |
- * Copyright (C) 2005 iptelorg GmbH |
|
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 |
-* \file |
|
18 |
-* \brief Kamailio core :: tcp io wait common stuff used by tcp_main.c & tcp_read.c |
|
19 |
-* \ingroup core |
|
20 |
-* Module: \ref core |
|
21 |
-* \author andrei |
|
22 |
-* |
|
23 |
- * All the functions are inline because of speed reasons and because they are |
|
24 |
- * used only from 2 places. |
|
25 |
- * |
|
26 |
- * You also have to define: |
|
27 |
- * int handle_io(struct fd_map* fm, short events, int idx) (see below) |
|
28 |
- * (this could be trivially replaced by a callback pointer entry attached |
|
29 |
- * to the io_wait handler if more flexibility rather then performance |
|
30 |
- * is needed) |
|
31 |
- * fd_type - define to some enum of you choice and define also |
|
32 |
- * FD_TYPE_DEFINED (if you don't do it fd_type will be defined |
|
33 |
- * to int). 0 has a special not set/not init. meaning |
|
34 |
- * (a lot of sanity checks and the sigio_rt code are based on |
|
35 |
- * this assumption) |
|
36 |
- * local_malloc (defaults to pkg_malloc) |
|
37 |
- * local_free (defaults to pkg_free) |
|
38 |
- * |
|
39 |
- */ |
|
40 |
- |
|
41 |
-#ifndef _io_wait_h |
|
42 |
-#define _io_wait_h |
|
43 |
- |
|
44 |
-#include <errno.h> |
|
45 |
-#include <string.h> |
|
46 |
-#ifdef HAVE_SIGIO_RT |
|
47 |
-#define __USE_GNU /* or else F_SETSIG won't be included */ |
|
48 |
-#include <sys/types.h> /* recv */ |
|
49 |
-#include <sys/socket.h> /* recv */ |
|
50 |
-#include <signal.h> /* sigprocmask, sigwait a.s.o */ |
|
51 |
-#endif |
|
52 |
- |
|
53 |
-#define _GNU_SOURCE /* for POLLRDHUP on linux */ |
|
54 |
-#include <poll.h> |
|
55 |
-#include <fcntl.h> |
|
56 |
- |
|
57 |
-#ifdef HAVE_EPOLL |
|
58 |
-#include <sys/epoll.h> |
|
59 |
-#endif |
|
60 |
-#ifdef HAVE_KQUEUE |
|
61 |
-#include <sys/types.h> /* needed on freebsd */ |
|
62 |
-#include <sys/event.h> |
|
63 |
-#include <sys/time.h> |
|
64 |
-#endif |
|
65 |
-#ifdef HAVE_DEVPOLL |
|
66 |
-#include <sys/devpoll.h> |
|
67 |
-#endif |
|
68 |
-#ifdef HAVE_SELECT |
|
69 |
-/* needed on openbsd for select*/ |
|
70 |
-#include <sys/time.h> |
|
71 |
-#include <sys/types.h> |
|
72 |
-#include <unistd.h> |
|
73 |
-/* needed according to POSIX for select*/ |
|
74 |
-#include <sys/select.h> |
|
75 |
-#endif |
|
76 |
- |
|
77 |
-#include "dprint.h" |
|
78 |
- |
|
79 |
-#include "poll_types.h" /* poll_types*/ |
|
80 |
-#ifdef HAVE_SIGIO_RT |
|
81 |
-#include "pt.h" /* mypid() */ |
|
82 |
-#endif |
|
83 |
- |
|
84 |
-#include "compiler_opt.h" |
|
85 |
- |
|
86 |
- |
|
87 |
-#ifdef HAVE_EPOLL |
|
88 |
-/* fix defines for EPOLL */ |
|
89 |
-#if defined POLLRDHUP && ! defined EPOLLRDHUP |
|
90 |
-#define EPOLLRDHUP POLLRDHUP /* should work on all linuxes */ |
|
91 |
-#endif /* POLLRDHUP && EPOLLRDHUP */ |
|
92 |
-#endif /* HAVE_EPOLL */ |
|
93 |
- |
|
94 |
- |
|
95 |
-extern int _os_ver; /* os version number, needed to select bugs workarrounds */ |
|
96 |
- |
|
97 |
- |
|
98 |
-#if 0 |
|
99 |
-enum fd_types; /* this should be defined from the including file, |
|
100 |
- see tcp_main.c for an example, |
|
101 |
- 0 has a special meaning: not used/empty*/ |
|
102 |
-#endif |
|
103 |
- |
|
104 |
-#ifndef FD_TYPE_DEFINED |
|
105 |
-typedef int fd_type; |
|
106 |
-#define FD_TYPE_DEFINED |
|
107 |
-#endif |
|
108 |
- |
|
109 |
-#ifdef __SUNPRO_C |
|
110 |
-#pragma weak handle_io |
|
111 |
-#endif |
|
112 |
- |
|
113 |
-/* maps a fd to some other structure; used in almost all cases |
|
114 |
- * except epoll and maybe kqueue or /dev/poll */ |
|
115 |
-struct fd_map{ |
|
116 |
- int fd; /* fd no */ |
|
117 |
- fd_type type; /* "data" type */ |
|
118 |
- void* data; /* pointer to the corresponding structure */ |
|
119 |
- short events; /* events we are interested int */ |
|
120 |
-}; |
|
121 |
- |
|
122 |
- |
|
123 |
-#ifdef HAVE_KQUEUE |
|
124 |
-#ifndef KQ_CHANGES_ARRAY_SIZE |
|
125 |
-#define KQ_CHANGES_ARRAY_SIZE 256 |
|
126 |
- |
|
127 |
-#ifdef __OS_netbsd |
|
128 |
-#define KEV_UDATA_CAST (intptr_t) |
|
129 |
-#else |
|
130 |
-#define KEV_UDATA_CAST |
|
131 |
-#endif |
|
132 |
- |
|
133 |
-#endif |
|
134 |
-#endif |
|
135 |
- |
|
136 |
- |
|
137 |
-/* handler structure */ |
|
138 |
-struct io_wait_handler{ |
|
139 |
- enum poll_types poll_method; |
|
140 |
- int flags; |
|
141 |
- struct fd_map* fd_hash; |
|
142 |
- int fd_no; /* current index used in fd_array and the passed size for |
|
143 |
- ep_array (for kq_array at least |
|
144 |
- max(twice the size, kq_changes_size) should be |
|
145 |
- be passed). */ |
|
146 |
- int max_fd_no; /* maximum fd no, is also the size of fd_array, |
|
147 |
- fd_hash and ep_array*/ |
|
148 |
- /* common stuff for POLL, SIGIO_RT and SELECT |
|
149 |
- * since poll support is always compiled => this will always be compiled */ |
|
150 |
- struct pollfd* fd_array; /* used also by devpoll as devpoll array */ |
|
151 |
- int crt_fd_array_idx; /* crt idx for which handle_io is called |
|
152 |
- (updated also by del -> internal optimization) */ |
|
153 |
- /* end of common stuff */ |
|
154 |
-#ifdef HAVE_EPOLL |
|
155 |
- int epfd; /* epoll ctrl fd */ |
|
156 |
- struct epoll_event* ep_array; |
|
157 |
-#endif |
|
158 |
-#ifdef HAVE_SIGIO_RT |
|
159 |
- sigset_t sset; /* signal mask for sigio & sigrtmin */ |
|
160 |
- int signo; /* real time signal used */ |
|
161 |
-#endif |
|
162 |
-#ifdef HAVE_KQUEUE |
|
163 |
- int kq_fd; |
|
164 |
- struct kevent* kq_array; /* used for the eventlist*/ |
|
165 |
- struct kevent* kq_changes; /* used for the changelist */ |
|
166 |
- size_t kq_nchanges; |
|
167 |
- size_t kq_array_size; /* array size */ |
|
168 |
- size_t kq_changes_size; /* size of the changes array */ |
|
169 |
-#endif |
|
170 |
-#ifdef HAVE_DEVPOLL |
|
171 |
- int dpoll_fd; |
|
172 |
-#endif |
|
173 |
-#ifdef HAVE_SELECT |
|
174 |
- fd_set master_rset; /* read set */ |
|
175 |
- fd_set master_wset; /* write set */ |
|
176 |
- int max_fd_select; /* maximum select used fd */ |
|
177 |
-#endif |
|
178 |
-}; |
|
179 |
- |
|
180 |
-typedef struct io_wait_handler io_wait_h; |
|
181 |
- |
|
182 |
- |
|
183 |
-/* get the corresponding fd_map structure pointer */ |
|
184 |
-#define get_fd_map(h, fd) (&(h)->fd_hash[(fd)]) |
|
185 |
-/* remove a fd_map structure from the hash; the pointer must be returned |
|
186 |
- * by get_fd_map or hash_fd_map*/ |
|
187 |
-#define unhash_fd_map(pfm) \ |
|
188 |
- do{ \ |
|
189 |
- (pfm)->type=0 /*F_NONE */; \ |
|
190 |
- (pfm)->fd=-1; \ |
|
191 |
- }while(0) |
|
192 |
- |
|
193 |
-/* add a fd_map structure to the fd hash */ |
|
194 |
-static inline struct fd_map* hash_fd_map( io_wait_h* h, |
|
195 |
- int fd, |
|
196 |
- short events, |
|
197 |
- fd_type type, |
|
198 |
- void* data) |
|
199 |
-{ |
|
200 |
- h->fd_hash[fd].fd=fd; |
|
201 |
- h->fd_hash[fd].events=events; |
|
202 |
- h->fd_hash[fd].type=type; |
|
203 |
- h->fd_hash[fd].data=data; |
|
204 |
- return &h->fd_hash[fd]; |
|
205 |
-} |
|
206 |
- |
|
207 |
- |
|
208 |
- |
|
209 |
-#ifdef HANDLE_IO_INLINE |
|
210 |
-/* generic handle io routine, this must be defined in the including file |
|
211 |
- * (faster then registering a callback pointer) |
|
212 |
- * |
|
213 |
- * params: fm - pointer to a fd hash entry |
|
214 |
- * events - combinations of POLLIN, POLLOUT, POLLERR & POLLHUP |
|
215 |
- * idx - index in the fd_array (or -1 if not known) |
|
216 |
- * return: -1 on error |
|
217 |
- * 0 on EAGAIN or when by some other way it is known that no more |
|
218 |
- * io events are queued on the fd (the receive buffer is empty). |
|
219 |
- * Usefull to detect when there are no more io events queued for |
|
220 |
- * sigio_rt, epoll_et, kqueue. |
|
221 |
- * >0 on successfull read from the fd (when there might be more io |
|
222 |
- * queued -- the receive buffer might still be non-empty) |
|
223 |
- */ |
|
224 |
-inline static int handle_io(struct fd_map* fm, short events, int idx); |
|
225 |
-#else |
|
226 |
-int handle_io(struct fd_map* fm, short events, int idx); |
|
227 |
-#endif |
|
228 |
- |
|
229 |
- |
|
230 |
- |
|
231 |
-#ifdef HAVE_KQUEUE |
|
232 |
-/* |
|
233 |
- * kqueue specific function: register a change |
|
234 |
- * (adds a change to the kevent change array, and if full flushes it first) |
|
235 |
- * |
|
236 |
- * TODO: check if the event already exists in the change list or if it's |
|
237 |
- * complementary to an event in the list (e.g. EVFILT_WRITE, EV_DELETE |
|
238 |
- * and EVFILT_WRITE, EV_ADD for the same fd). |
|
239 |
- * returns: -1 on error, 0 on success |
|
240 |
- */ |
|
241 |
-static inline int kq_ev_change(io_wait_h* h, int fd, int filter, int flag, |
|
242 |
- void* data) |
|
243 |
-{ |
|
244 |
- int n; |
|
245 |
- int r; |
|
246 |
- struct timespec tspec; |
|
247 |
- |
|
248 |
- if (h->kq_nchanges>=h->kq_changes_size){ |
|
249 |
- /* changes array full ! */ |
|
250 |
- LM_WARN("kqueue changes array full trying to flush...\n"); |
|
251 |
- tspec.tv_sec=0; |
|
252 |
- tspec.tv_nsec=0; |
|
253 |
-again: |
|
254 |
- n=kevent(h->kq_fd, h->kq_changes, h->kq_nchanges, 0, 0, &tspec); |
|
255 |
- if (unlikely(n == -1)){ |
|
256 |
- if (unlikely(errno == EINTR)) goto again; |
|
257 |
- else { |
|
258 |
- /* for a detailed explanation of what follows see |
|
259 |
- io_wait_loop_kqueue EV_ERROR case */ |
|
260 |
- if (unlikely(!(errno == EBADF || errno == ENOENT))) |
|
261 |
- BUG("kq_ev_change: kevent flush changes failed" |
|
262 |
- " (unexpected error): %s [%d]\n", |
|
263 |
- strerror(errno), errno); |
|
264 |
- /* ignore error even if it's not a EBADF/ENOENT */ |
|
265 |
- /* one of the file descriptors is bad, probably already |
|
266 |
- closed => try to apply changes one-by-one */ |
|
267 |
- for (r = 0; r < h->kq_nchanges; r++) { |
|
268 |
-retry2: |
|
269 |
- n = kevent(h->kq_fd, &h->kq_changes[r], 1, 0, 0, &tspec); |
|
270 |
- if (n==-1) { |
|
271 |
- if (unlikely(errno == EINTR)) |
|
272 |
- goto retry2; |
|
273 |
- /* for a detailed explanation of what follows see |
|
274 |
- io_wait_loop_kqueue EV_ERROR case */ |
|
275 |
- if (unlikely(!(errno == EBADF || errno == ENOENT))) |
|
276 |
- BUG("kq_ev_change: kevent flush changes failed:" |
|
277 |
- " (unexpected error) %s [%d] (%d/%lu)\n", |
|
278 |
- strerror(errno), errno, |
|
279 |
- r, (unsigned long)h->kq_nchanges); |
|
280 |
- continue; /* skip over it */ |
|
281 |
- } |
|
282 |
- } |
|
283 |
- } |
|
284 |
- } |
|
285 |
- h->kq_nchanges=0; /* changes array is empty */ |
|
286 |
- } |
|
287 |
- EV_SET(&h->kq_changes[h->kq_nchanges], fd, filter, flag, 0, 0, |
|
288 |
- KEV_UDATA_CAST data); |
|
289 |
- h->kq_nchanges++; |
|
290 |
- return 0; |
|
291 |
-} |
|
292 |
-#endif |
|
293 |
- |
|
294 |
- |
|
295 |
- |
|
296 |
-/* generic io_watch_add function |
|
297 |
- * Params: |
|
298 |
- * h - pointer to initialized io_wait handle |
|
299 |
- * fd - fd to watch |
|
300 |
- * events - bitmap with the fd events for which the fd should be watched |
|
301 |
- * (combination of POLLIN and POLLOUT) |
|
302 |
- * type - fd type (non 0 value, returned in the call to handle_io) |
|
303 |
- * data - pointer/private data returned in the handle_io call |
|
304 |
- * returns 0 on success, -1 on error |
|
305 |
- * |
|
306 |
- * WARNING: handle_io() can be called immediately (from io_watch_add()) so |
|
307 |
- * make sure that any dependent init. (e.g. data stuff) is made before |
|
308 |
- * calling io_watch_add |
|
309 |
- * |
|
310 |
- * this version should be faster than pointers to poll_method specific |
|
311 |
- * functions (it avoids functions calls, the overhead being only an extra |
|
312 |
- * switch())*/ |
|
313 |
-inline static int io_watch_add( io_wait_h* h, |
|
314 |
- int fd, |
|
315 |
- short events, |
|
316 |
- fd_type type, |
|
317 |
- void* data) |
|
318 |
-{ |
|
319 |
- |
|
320 |
- /* helper macros */ |
|
321 |
-#define fd_array_setup(ev) \ |
|
322 |
- do{ \ |
|
323 |
- h->fd_array[h->fd_no].fd=fd; \ |
|
324 |
- h->fd_array[h->fd_no].events=(ev); /* useless for select */ \ |
|
325 |
- h->fd_array[h->fd_no].revents=0; /* useless for select */ \ |
|
326 |
- }while(0) |
|
327 |
- |
|
328 |
-#define set_fd_flags(f) \ |
|
329 |
- do{ \ |
|
330 |
- flags=fcntl(fd, F_GETFL); \ |
|
331 |
- if (flags==-1){ \ |
|
332 |
- LM_ERR("fnctl: GETFL failed: %s [%d]\n", \ |
|
333 |
- strerror(errno), errno); \ |
|
334 |
- goto error; \ |
|
335 |
- } \ |
|
336 |
- if (fcntl(fd, F_SETFL, flags|(f))==-1){ \ |
|
337 |
- LM_ERR("fnctl: SETFL failed: %s [%d]\n", \ |
|
338 |
- strerror(errno), errno); \ |
|
339 |
- goto error; \ |
|
340 |
- } \ |
|
341 |
- }while(0) |
|
342 |
- |
|
343 |
- |
|
344 |
- struct fd_map* e; |
|
345 |
- int flags; |
|
346 |
-#ifdef HAVE_EPOLL |
|
347 |
- struct epoll_event ep_event; |
|
348 |
-#endif |
|
349 |
-#ifdef HAVE_DEVPOLL |
|
350 |
- struct pollfd pfd; |
|
351 |
-#endif |
|
352 |
-#if defined(HAVE_SIGIO_RT) || defined (HAVE_EPOLL) |
|
353 |
- int n; |
|
354 |
-#endif |
|
355 |
-#if defined(HAVE_SIGIO_RT) |
|
356 |
- int idx; |
|
357 |
- int check_io; |
|
358 |
- struct pollfd pf; |
|
359 |
- |
|
360 |
- check_io=0; /* set to 1 if we need to check for pre-existing queued |
|
361 |
- io/data on the fd */ |
|
362 |
- idx=-1; |
|
363 |
-#endif |
|
364 |
- e=0; |
|
365 |
- /* sanity checks */ |
|
366 |
- if (unlikely(fd==-1)){ |
|
367 |
- LM_CRIT("fd is -1!\n"); |
|
368 |
- goto error; |
|
369 |
- } |
|
370 |
- if (unlikely((events&(POLLIN|POLLOUT))==0)){ |
|
371 |
- LM_CRIT("invalid events: 0x%0x\n", events); |
|
372 |
- goto error; |
|
373 |
- } |
|
374 |
- /* check if not too big */ |
|
375 |
- if (unlikely(h->fd_no>=h->max_fd_no)){ |
|
376 |
- LM_CRIT("maximum fd number exceeded: %d/%d\n", h->fd_no, h->max_fd_no); |
|
377 |
- goto error; |
|
378 |
- } |
|
379 |
- DBG("DBG: io_watch_add(%p, %d, %d, %p), fd_no=%d\n", |
|
380 |
- h, fd, type, data, h->fd_no); |
|
381 |
- /* hash sanity check */ |
|
382 |
- e=get_fd_map(h, fd); |
|
383 |
- if (unlikely(e && (e->type!=0 /*F_NONE*/))){ |
|
384 |
- LM_ERR("trying to overwrite entry %d" |
|
385 |
- " watched for %x in the hash(%d, %d, %p) with (%d, %d, %p)\n", |
|
386 |
- fd, events, e->fd, e->type, e->data, fd, type, data); |
|
387 |
- e=0; |
|
388 |
- goto error; |
|
389 |
- } |
|
390 |
- |
|
391 |
- if (unlikely((e=hash_fd_map(h, fd, events, type, data))==0)){ |
|
392 |
- LM_ERR("failed to hash the fd %d\n", fd); |
|
393 |
- goto error; |
|
394 |
- } |
|
395 |
- switch(h->poll_method){ /* faster then pointer to functions */ |
|
396 |
- case POLL_POLL: |
|
397 |
-#ifdef POLLRDHUP |
|
398 |
- /* listen to POLLRDHUP by default (if POLLIN) */ |
|
399 |
- events|=((int)!(events & POLLIN) - 1) & POLLRDHUP; |
|
400 |
-#endif /* POLLRDHUP */ |
|
401 |
- fd_array_setup(events); |
|
402 |
- set_fd_flags(O_NONBLOCK); |
|
403 |
- break; |
|
404 |
-#ifdef HAVE_SELECT |
|
405 |
- case POLL_SELECT: |
|
406 |
- fd_array_setup(events); |
|
407 |
- if (likely(events & POLLIN)) |
|
408 |
- FD_SET(fd, &h->master_rset); |
|
409 |
- if (unlikely(events & POLLOUT)) |
|
410 |
- FD_SET(fd, &h->master_wset); |
|
411 |
- if (h->max_fd_select<fd) h->max_fd_select=fd; |
|
412 |
- break; |
|
413 |
-#endif |
|
414 |
-#ifdef HAVE_SIGIO_RT |
|
415 |
- case POLL_SIGIO_RT: |
|
416 |
- fd_array_setup(events); |
|
417 |
- /* re-set O_ASYNC might be needed, if not done from |
|
418 |
- * io_watch_del (or if somebody wants to add a fd which has |
|
419 |
- * already O_ASYNC/F_SETSIG set on a duplicate) |
|
420 |
- */ |
|
421 |
- /* set async & signal */ |
|
422 |
- if (fcntl(fd, F_SETOWN, my_pid())==-1){ |
|
423 |
- LM_ERR("fnctl: SETOWN failed: %s [%d]\n", |
|
424 |
- strerror(errno), errno); |
|
425 |
- goto error; |
|
426 |
- } |
|
427 |
- if (fcntl(fd, F_SETSIG, h->signo)==-1){ |
|
428 |
- LM_ERR("fnctl: SETSIG failed: %s [%d]\n", |
|
429 |
- strerror(errno), errno); |
|
430 |
- goto error; |
|
431 |
- } |
|
432 |
- /* set both non-blocking and async */ |
|
433 |
- set_fd_flags(O_ASYNC| O_NONBLOCK); |
|
434 |
-#ifdef EXTRA_DEBUG |
|
435 |
- DBG("io_watch_add: sigio_rt on f %d, signal %d to pid %d\n", |
|
436 |
- fd, h->signo, my_pid()); |
|
437 |
-#endif |
|
438 |
- /* empty socket receive buffer, if buffer is already full |
|
439 |
- * no more space to put packets |
|
440 |
- * => no more signals are ever generated |
|
441 |
- * also when moving fds, the freshly moved fd might have |
|
442 |
- * already some bytes queued, we want to get them now |
|
443 |
- * and not later -- andrei */ |
|
444 |
- idx=h->fd_no; |
|
445 |
- check_io=1; |
|
446 |
- break; |
|
447 |
-#endif |
|
448 |
-#ifdef HAVE_EPOLL |
|
449 |
- case POLL_EPOLL_LT: |
|
450 |
- ep_event.events= |
|
451 |
-#ifdef POLLRDHUP |
|
452 |
- /* listen for EPOLLRDHUP too */ |
|
453 |
- ((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) | |
|
454 |
-#else /* POLLRDHUP */ |
|
455 |
- (EPOLLIN & ((int)!(events & POLLIN)-1) ) | |
|
456 |
-#endif /* POLLRDHUP */ |
|
457 |
- (EPOLLOUT & ((int)!(events & POLLOUT)-1) ); |
|
458 |
- ep_event.data.ptr=e; |
|
459 |
-again1: |
|
460 |
- n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event); |
|
461 |
- if (unlikely(n==-1)){ |
|
462 |
- if (errno==EAGAIN) goto again1; |
|
463 |
- LM_ERR("epoll_ctl failed: %s [%d]\n", strerror(errno), errno); |
|
464 |
- goto error; |
|
465 |
- } |
|
466 |
- break; |
|
467 |
- case POLL_EPOLL_ET: |
|
468 |
- set_fd_flags(O_NONBLOCK); |
|
469 |
- ep_event.events= |
|
470 |
-#ifdef POLLRDHUP |
|
471 |
- /* listen for EPOLLRDHUP too */ |
|
472 |
- ((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) | |
|
473 |
-#else /* POLLRDHUP */ |
|
474 |
- (EPOLLIN & ((int)!(events & POLLIN)-1) ) | |
|
475 |
-#endif /* POLLRDHUP */ |
|
476 |
- (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) | |
|
477 |
- EPOLLET; |
|
478 |
- ep_event.data.ptr=e; |
|
479 |
-again2: |
|
480 |
- n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event); |
|
481 |
- if (unlikely(n==-1)){ |
|
482 |
- if (errno==EAGAIN) goto again2; |
|
483 |
- LM_ERR("epoll_ctl failed: %s [%d]\n", strerror(errno), errno); |
|
484 |
- goto error; |
|
485 |
- } |
|
486 |
- break; |
|
487 |
-#endif |
|
488 |
-#ifdef HAVE_KQUEUE |
|
489 |
- case POLL_KQUEUE: |
|
490 |
- if (likely( events & POLLIN)){ |
|
491 |
- if (unlikely(kq_ev_change(h, fd, EVFILT_READ, EV_ADD, e)==-1)) |
|
492 |
- goto error; |
|
493 |
- } |
|
494 |
- if (unlikely( events & POLLOUT)){ |
|
495 |
- if (unlikely(kq_ev_change(h, fd, EVFILT_WRITE, EV_ADD, e)==-1)) |
|
496 |
- { |
|
497 |
- if (likely(events & POLLIN)){ |
|
498 |
- kq_ev_change(h, fd, EVFILT_READ, EV_DELETE, 0); |
|
499 |
- } |
|
500 |
- goto error; |
|
501 |
- } |
|
502 |
- } |
|
503 |
- break; |
|
504 |
-#endif |
|
505 |
-#ifdef HAVE_DEVPOLL |
|
506 |
- case POLL_DEVPOLL: |
|
507 |
- pfd.fd=fd; |
|
508 |
- pfd.events=events; |
|
509 |
- pfd.revents=0; |
|
510 |
-again_devpoll: |
|
511 |
- if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){ |
|
512 |
- if (errno==EAGAIN) goto again_devpoll; |
|
513 |
- LM_ERR("/dev/poll write failed: %s [%d]\n", |
|
514 |
- strerror(errno), errno); |
|
515 |
- goto error; |
|
516 |
- } |
|
517 |
- break; |
|
518 |
-#endif |
|
519 |
- |
|
520 |
- default: |
|
521 |
- LM_CRIT("no support for poll method %s (%d)\n", |
|
522 |
- poll_method_str[h->poll_method], h->poll_method); |
|
523 |
- goto error; |
|
524 |
- } |
|
525 |
- |
|
526 |
- h->fd_no++; /* "activate" changes, for epoll/kqueue/devpoll it |
|
527 |
- has only informative value */ |
|
528 |
-#if defined(HAVE_SIGIO_RT) |
|
529 |
- if (check_io){ |
|
530 |
- /* handle possible pre-existing events */ |
|
531 |
- pf.fd=fd; |
|
532 |
- pf.events=events; |
|
533 |
-check_io_again: |
|
534 |
- n=0; |
|
535 |
- while(e->type && ((n=poll(&pf, 1, 0))>0) && |
|
536 |
- (handle_io(e, pf.revents, idx)>0) && |
|
537 |
- (pf.revents & (e->events|POLLERR|POLLHUP))); |
|
538 |
- if (unlikely(e->type && (n==-1))){ |
|
539 |
- if (errno==EINTR) goto check_io_again; |
|
540 |
- LM_ERR("check_io poll: %s [%d]\n", strerror(errno), errno); |
|
541 |
- } |
|
542 |
- } |
|
543 |
-#endif |
|
544 |
- return 0; |
|
545 |
-error: |
|
546 |
- if (e) unhash_fd_map(e); |
|
547 |
- return -1; |
|
548 |
-#undef fd_array_setup |
|
549 |
-#undef set_fd_flags |
|
550 |
-} |
|
551 |
- |
|
552 |
- |
|
553 |
- |
|
554 |
-#define IO_FD_CLOSING 16 |
|
555 |
-/* parameters: h - handler |
|
556 |
- * fd - file descriptor |
|
557 |
- * index - index in the fd_array if known, -1 if not |
|
558 |
- * (if index==-1 fd_array will be searched for the |
|
559 |
- * corresponding fd* entry -- slower but unavoidable in |
|
560 |
- * some cases). index is not used (no fd_array) for epoll, |
|
561 |
- * /dev/poll and kqueue |
|
562 |
- * flags - optimization flags, e.g. IO_FD_CLOSING, the fd was |
|
563 |
- * or will shortly be closed, in some cases we can avoid |
|
564 |
- * extra remove operations (e.g.: epoll, kqueue, sigio) |
|
565 |
- * returns 0 if ok, -1 on error */ |
|
566 |
-inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags) |
|
567 |
-{ |
|
568 |
- |
|
569 |
-#define fix_fd_array \ |
|
570 |
- do{\ |
|
571 |
- if (unlikely(idx==-1)){ \ |
|
572 |
- /* fix idx if -1 and needed */ \ |
|
573 |
- for (idx=0; (idx<h->fd_no) && \ |
|
574 |
- (h->fd_array[idx].fd!=fd); idx++); \ |
|
575 |
- } \ |
|
576 |
- if (likely(idx<h->fd_no)){ \ |
|
577 |
- memmove(&h->fd_array[idx], &h->fd_array[idx+1], \ |
|
578 |
- (h->fd_no-(idx+1))*sizeof(*(h->fd_array))); \ |
|
579 |
- if ((idx<=h->crt_fd_array_idx) && (h->crt_fd_array_idx>=0)) \ |
|
580 |
- h->crt_fd_array_idx--; \ |
|
581 |
- } \ |
|
582 |
- }while(0) |
|
583 |
- |
|
584 |
- struct fd_map* e; |
|
585 |
- int events; |
|
586 |
-#ifdef HAVE_EPOLL |
|
587 |
- int n; |
|
588 |
- struct epoll_event ep_event; |
|
589 |
-#endif |
|
590 |
-#ifdef HAVE_DEVPOLL |
|
591 |
- struct pollfd pfd; |
|
592 |
-#endif |
|
593 |
-#ifdef HAVE_SIGIO_RT |
|
594 |
- int fd_flags; |
|
595 |
-#endif |
|
596 |
- |
|
597 |
- if (unlikely((fd<0) || (fd>=h->max_fd_no))){ |
|
598 |
- LM_CRIT("invalid fd %d, not in [0, %d) \n", fd, h->fd_no); |
|
599 |
- goto error; |
|
600 |
- } |
|
601 |
- DBG("DBG: io_watch_del (%p, %d, %d, 0x%x) fd_no=%d called\n", |
|
602 |
- h, fd, idx, flags, h->fd_no); |
|
603 |
- e=get_fd_map(h, fd); |
|
604 |
- /* more sanity checks */ |
|
605 |
- if (unlikely(e==0)){ |
|
606 |
- LM_CRIT("no corresponding hash entry for %d\n", fd); |
|
607 |
- goto error; |
|
608 |
- } |
|
609 |
- if (unlikely(e->type==0 /*F_NONE*/)){ |
|
610 |
- LM_ERR("trying to delete already erased" |
|
611 |
- " entry %d in the hash(%d, %d, %p) flags %x)\n", |
|
612 |
- fd, e->fd, e->type, e->data, flags); |
|
613 |
- goto error; |
|
614 |
- } |
|
615 |
- events=e->events; |
|
616 |
- |
|
617 |
- switch(h->poll_method){ |
|
618 |
- case POLL_POLL: |
|
619 |
- fix_fd_array; |
|
620 |
- break; |
|
621 |
-#ifdef HAVE_SELECT |
|
622 |
- case POLL_SELECT: |
|
623 |
- if (likely(events & POLLIN)) |
|
624 |
- FD_CLR(fd, &h->master_rset); |
|
625 |
- if (unlikely(events & POLLOUT)) |
|
626 |
- FD_CLR(fd, &h->master_wset); |
|
627 |
- if (unlikely(h->max_fd_select && (h->max_fd_select==fd))) |
|
628 |
- /* we don't know the prev. max, so we just decrement it */ |
|
629 |
- h->max_fd_select--; |
|
630 |
- fix_fd_array; |
|
631 |
- break; |
|
632 |
-#endif |
|
633 |
-#ifdef HAVE_SIGIO_RT |
|
634 |
- case POLL_SIGIO_RT: |
|
635 |
- /* the O_ASYNC flag must be reset all the time, the fd |
|
636 |
- * can be changed only if O_ASYNC is reset (if not and |
|
637 |
- * the fd is a duplicate, you will get signals from the dup. fd |
|
638 |
- * and not from the original, even if the dup. fd was closed |
|
639 |
- * and the signals re-set on the original) -- andrei |
|
640 |
- */ |
|
641 |
- /*if (!(flags & IO_FD_CLOSING)){*/ |
|
642 |
- /* reset ASYNC */ |
|
643 |
- fd_flags=fcntl(fd, F_GETFL); |
|
644 |
- if (unlikely(fd_flags==-1)){ |
|
645 |
- LM_ERR("fnctl: GETFL failed: %s [%d]\n", |
|
646 |
- strerror(errno), errno); |
|
647 |
- goto error; |
|
648 |
- } |
|
649 |
- if (unlikely(fcntl(fd, F_SETFL, fd_flags&(~O_ASYNC))==-1)){ |
|
650 |
- LM_ERR("fnctl: SETFL failed: %s [%d]\n", |
|
651 |
- strerror(errno), errno); |
|
652 |
- goto error; |
|
653 |
- } |
|
654 |
- fix_fd_array; /* only on success */ |
|
655 |
- break; |
|
656 |
-#endif |
|
657 |
-#ifdef HAVE_EPOLL |
|
658 |
- case POLL_EPOLL_LT: |
|
659 |
- case POLL_EPOLL_ET: |
|
660 |
- /* epoll doesn't seem to automatically remove sockets, |
|
661 |
- * if the socket is a duplicate/moved and the original |
|
662 |
- * is still open. The fd is removed from the epoll set |
|
663 |
- * only when the original (and all the copies?) is/are |
|
664 |
- * closed. This is probably a bug in epoll. --andrei */ |
|
665 |
-#ifdef EPOLL_NO_CLOSE_BUG |
|
666 |
- if (!(flags & IO_FD_CLOSING)){ |
|
667 |
-#endif |
|
668 |
-again_epoll: |
|
669 |
- n=epoll_ctl(h->epfd, EPOLL_CTL_DEL, fd, &ep_event); |
|
670 |
- if (unlikely(n==-1)){ |
|
671 |
- if (errno==EAGAIN) goto again_epoll; |
|
672 |
- LM_ERR("removing fd from epoll list failed: %s [%d]\n", |
|
673 |
- strerror(errno), errno); |
|
674 |
- goto error; |
|
675 |
- } |
|
676 |
-#ifdef EPOLL_NO_CLOSE_BUG |
|
677 |
- } |
|
678 |
-#endif |
|
679 |
- break; |
|
680 |
-#endif |
|
681 |
-#ifdef HAVE_KQUEUE |
|
682 |
- case POLL_KQUEUE: |
|
683 |
- if (!(flags & IO_FD_CLOSING)){ |
|
684 |
- if (likely(events & POLLIN)){ |
|
685 |
- if (unlikely(kq_ev_change(h, fd, EVFILT_READ, |
|
686 |
- EV_DELETE, 0) ==-1)){ |
|
687 |
- /* try to delete the write filter anyway */ |
|
688 |
- if (events & POLLOUT){ |
|
689 |
- kq_ev_change(h, fd, EVFILT_WRITE, EV_DELETE, 0); |
|
690 |
- } |
|
691 |
- goto error; |
|
692 |
- } |
|
693 |
- } |
|
694 |
- if (unlikely(events & POLLOUT)){ |
|
695 |
- if (unlikely(kq_ev_change(h, fd, EVFILT_WRITE, |
|
696 |
- EV_DELETE, 0) ==-1)) |
|
697 |
- goto error; |
|
698 |
- } |
|
699 |
- } |
|
700 |
- break; |
|
701 |
-#endif |
|
702 |
-#ifdef HAVE_DEVPOLL |
|
703 |
- case POLL_DEVPOLL: |
|
704 |
- /* for /dev/poll the closed fds _must_ be removed |
|
705 |
- (they are not removed automatically on close()) */ |
|
706 |
- pfd.fd=fd; |
|
707 |
- pfd.events=POLLREMOVE; |
|
708 |
- pfd.revents=0; |
|
709 |
-again_devpoll: |
|
710 |
- if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){ |
|
711 |
- if (errno==EINTR) goto again_devpoll; |
|
712 |
- LM_ERR("removing fd from /dev/poll failed: %s [%d]\n", |
|
713 |
- strerror(errno), errno); |
|
714 |
- goto error; |
|
715 |
- } |
|
716 |
- break; |
|
717 |
-#endif |
|
718 |
- default: |
|
719 |
- LM_CRIT("no support for poll method %s (%d)\n", |
|
720 |
- poll_method_str[h->poll_method], h->poll_method); |
|
721 |
- goto error; |
|
722 |
- } |
|
723 |
- unhash_fd_map(e); /* only on success */ |
|
724 |
- h->fd_no--; |
|
725 |
- return 0; |
|
726 |
-error: |
|
727 |
- return -1; |
|
728 |
-#undef fix_fd_array |
|
729 |
-} |
|
730 |
- |
|
731 |
- |
|
732 |
- |
|
733 |
-/* parameters: h - handler |
|
734 |
- * fd - file descriptor |
|
735 |
- * events - new events to watch for |
|
736 |
- * idx - index in the fd_array if known, -1 if not |
|
737 |
- * (if index==-1 fd_array will be searched for the |
|
738 |
- * corresponding fd* entry -- slower but unavoidable in |
|
739 |
- * some cases). index is not used (no fd_array) for epoll, |
|
740 |
- * /dev/poll and kqueue |
|
741 |
- * returns 0 if ok, -1 on error */ |
|
742 |
-inline static int io_watch_chg(io_wait_h* h, int fd, short events, int idx ) |
|
743 |
-{ |
|
744 |
- |
|
745 |
-#define fd_array_chg(ev) \ |
|
746 |
- do{\ |
|
747 |
- if (unlikely(idx==-1)){ \ |
|
748 |
- /* fix idx if -1 and needed */ \ |
|
749 |
- for (idx=0; (idx<h->fd_no) && \ |
|
750 |
- (h->fd_array[idx].fd!=fd); idx++); \ |
|
751 |
- } \ |
|
752 |
- if (likely(idx<h->fd_no)){ \ |
|
753 |
- h->fd_array[idx].events=(ev); \ |
|
754 |
- } \ |
|
755 |
- }while(0) |
|
756 |
- |
|
757 |
- struct fd_map* e; |
|
758 |
- int add_events; |
|
759 |
- int del_events; |
|
760 |
-#ifdef HAVE_DEVPOLL |
|
761 |
- struct pollfd pfd; |
|
762 |
-#endif |
|
763 |
-#ifdef HAVE_EPOLL |
|
764 |
- int n; |
|
765 |
- struct epoll_event ep_event; |
|
766 |
-#endif |
|
767 |
- |
|
768 |
- if (unlikely((fd<0) || (fd>=h->max_fd_no))){ |
|
769 |
- LM_CRIT("invalid fd %d, not in [0, %d) \n", fd, h->fd_no); |
|
770 |
- goto error; |
|
771 |
- } |
|
772 |
- if (unlikely((events&(POLLIN|POLLOUT))==0)){ |
|
773 |
- LM_CRIT("invalid events: 0x%0x\n", events); |
|
774 |
- goto error; |
|
775 |
- } |
|
776 |
- DBG("DBG: io_watch_chg (%p, %d, 0x%x, 0x%x) fd_no=%d called\n", |
|
777 |
- h, fd, events, idx, h->fd_no); |
|
778 |
- e=get_fd_map(h, fd); |
|
779 |
- /* more sanity checks */ |
|
780 |
- if (unlikely(e==0)){ |
|
781 |
- LM_CRIT("no corresponding hash entry for %d\n", fd); |
|
782 |
- goto error; |
|
783 |
- } |
|
784 |
- if (unlikely(e->type==0 /*F_NONE*/)){ |
|
785 |
- LM_ERR("trying to change an already erased" |
|
786 |
- " entry %d in the hash(%d, %d, %p) )\n", |
|
787 |
- fd, e->fd, e->type, e->data); |
|
788 |
- goto error; |
|
789 |
- } |
|
790 |
- |
|
791 |
- add_events=events & ~e->events; |
|
792 |
- del_events=e->events & ~events; |
|
793 |
- switch(h->poll_method){ |
|
794 |
- case POLL_POLL: |
|
795 |
-#ifdef POLLRDHUP |
|
796 |
- fd_array_chg(events | |
|
797 |
- /* listen to POLLRDHUP by default (if POLLIN) */ |
|
798 |
- (((int)!(events & POLLIN) - 1) & POLLRDHUP) |
|
799 |
- ); |
|
800 |
-#else /* POLLRDHUP */ |
|
801 |
- fd_array_chg(events); |
|
802 |
-#endif /* POLLRDHUP */ |
|
803 |
- break; |
|
804 |
-#ifdef HAVE_SELECT |
|
805 |
- case POLL_SELECT: |
|
806 |
- fd_array_chg(events); |
|
807 |
- if (unlikely(del_events & POLLIN)) |
|
808 |
- FD_CLR(fd, &h->master_rset); |
|
809 |
- else if (unlikely(add_events & POLLIN)) |
|
810 |
- FD_SET(fd, &h->master_rset); |
|
811 |
- if (likely(del_events & POLLOUT)) |
|
812 |
- FD_CLR(fd, &h->master_wset); |
|
813 |
- else if (likely(add_events & POLLOUT)) |
|
814 |
- FD_SET(fd, &h->master_wset); |
|
815 |
- break; |
|
816 |
-#endif |
|
817 |
-#ifdef HAVE_SIGIO_RT |
|
818 |
- case POLL_SIGIO_RT: |
|
819 |
- fd_array_chg(events); |
|
820 |
- /* no need for check_io, since SIGIO_RT listens by default for all |
|
821 |
- * the events */ |
|
822 |
- break; |
|
823 |
-#endif |
|
824 |
-#ifdef HAVE_EPOLL |
|
825 |
- case POLL_EPOLL_LT: |
|
826 |
- ep_event.events= |
|
827 |
-#ifdef POLLRDHUP |
|
828 |
- /* listen for EPOLLRDHUP too */ |
|
829 |
- ((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) | |
|
830 |
-#else /* POLLRDHUP */ |
|
831 |
- (EPOLLIN & ((int)!(events & POLLIN)-1) ) | |
|
832 |
-#endif /* POLLRDHUP */ |
|
833 |
- (EPOLLOUT & ((int)!(events & POLLOUT)-1) ); |
|
834 |
- ep_event.data.ptr=e; |
|
835 |
-again_epoll_lt: |
|
836 |
- n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event); |
|
837 |
- if (unlikely(n==-1)){ |
|
838 |
- if (errno==EAGAIN) goto again_epoll_lt; |
|
839 |
- LM_ERR("modifying epoll events failed: %s [%d]\n", |
|
840 |
- strerror(errno), errno); |
|
841 |
- goto error; |
|
842 |
- } |
|
843 |
- break; |
|
844 |
- case POLL_EPOLL_ET: |
|
845 |
- ep_event.events= |
|
846 |
-#ifdef POLLRDHUP |
|
847 |
- /* listen for EPOLLRDHUP too */ |
|
848 |
- ((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) | |
|
849 |
-#else /* POLLRDHUP */ |
|
850 |
- (EPOLLIN & ((int)!(events & POLLIN)-1) ) | |
|
851 |
-#endif /* POLLRDHUP */ |
|
852 |
- (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) | |
|
853 |
- EPOLLET; |
|
854 |
- ep_event.data.ptr=e; |
|
855 |
-again_epoll_et: |
|
856 |
- n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event); |
|
857 |
- if (unlikely(n==-1)){ |
|
858 |
- if (errno==EAGAIN) goto again_epoll_et; |
|
859 |
- LM_ERR("modifying epoll events failed: %s [%d]\n", |
|
860 |
- strerror(errno), errno); |
|
861 |
- goto error; |
|
862 |
- } |
|
863 |
- break; |
|
864 |
-#endif |
|
865 |
-#ifdef HAVE_KQUEUE |
|
866 |
- case POLL_KQUEUE: |
|
867 |
- if (unlikely(del_events & POLLIN)){ |
|
868 |
- if (unlikely(kq_ev_change(h, fd, EVFILT_READ, |
|
869 |
- EV_DELETE, 0) ==-1)) |
|
870 |
- goto error; |
|
871 |
- }else if (unlikely(add_events & POLLIN)){ |
|
872 |
- if (unlikely(kq_ev_change(h, fd, EVFILT_READ, EV_ADD, e) ==-1)) |
|
873 |
- goto error; |
|
874 |
- } |
|
875 |
- if (likely(del_events & POLLOUT)){ |
|
876 |
- if (unlikely(kq_ev_change(h, fd, EVFILT_WRITE, |
|
877 |
- EV_DELETE, 0) ==-1)) |
|
878 |
- goto error; |
|
879 |
- }else if (likely(add_events & POLLOUT)){ |
|
880 |
- if (unlikely(kq_ev_change(h, fd, EVFILT_WRITE, EV_ADD, e)==-1)) |
|
881 |
- goto error; |
|
882 |
- } |
|
883 |
- break; |
|
884 |
-#endif |
|
885 |
-#ifdef HAVE_DEVPOLL |
|
886 |
- case POLL_DEVPOLL: |
|
887 |
- /* for /dev/poll the closed fds _must_ be removed |
|
888 |
- (they are not removed automatically on close()) */ |
|
889 |
- pfd.fd=fd; |
|
890 |
- pfd.events=POLLREMOVE; |
|
891 |
- pfd.revents=0; |
|
892 |
-again_devpoll1: |
|
893 |
- if (unlikely(write(h->dpoll_fd, &pfd, sizeof(pfd))==-1)){ |
|
894 |
- if (errno==EINTR) goto again_devpoll1; |
|
895 |
- LM_ERR("removing fd from /dev/poll failed: %s [%d]\n", |
|
896 |
- strerror(errno), errno); |
|
897 |
- goto error; |
|
898 |
- } |
|
899 |
-again_devpoll2: |
|
900 |
- pfd.events=events; |
|
901 |
- pfd.revents=0; |
|
902 |
- if (unlikely(write(h->dpoll_fd, &pfd, sizeof(pfd))==-1)){ |
|
903 |