Modifying the return value of cfg_set* functions, in order to make
[sip-router] / io_wait.h
1 /* 
2  * $Id$
3  * 
4  * Copyright (C) 2005 iptelorg GmbH
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 /*
19  * tcp io wait common stuff used by tcp_main.c & tcp_read.c
20  * All the functions are inline because of speed reasons and because they are
21  * used only from 2 places.
22  * You also have to define:
23  *     int handle_io(struct fd_map* fm, short events, int idx) (see below)
24  *     (this could be trivially replaced by a callback pointer entry attached
25  *      to the io_wait handler if more flexibility rather then performance
26  *      is needed)
27  *      fd_type - define to some enum of you choice and define also
28  *                FD_TYPE_DEFINED (if you don't do it fd_type will be defined
29  *                to int). 0 has a special not set/not init. meaning
30  *                (a lot of sanity checks and the sigio_rt code are based on
31  *                 this assumption)
32  *     local_malloc (defaults to pkg_malloc)
33  *     local_free   (defaults to pkg_free)
34  *  
35  */
36 /* 
37  * History:
38  * --------
39  *  2005-06-13  created by andrei
40  *  2005-06-26  added kqueue (andrei)
41  *  2005-07-01  added /dev/poll (andrei)
42  *  2006-05-30  sigio 64 bit workarround enabled for kernels < 2.6.5 (andrei)
43  *  2007-11-22  when handle_io() is called in a loop check & stop if the fd was
44  *               removed inside handle_io() (andrei)
45  *  2007-11-29  support for write (POLLOUT); added io_watch_chg() (andrei)
46  */
47
48
49
50 #ifndef _io_wait_h
51 #define _io_wait_h
52
53 #include <errno.h>
54 #include <string.h>
55 #ifdef HAVE_SIGIO_RT
56 #define __USE_GNU /* or else F_SETSIG won't be included */
57 #include <sys/types.h> /* recv */
58 #include <sys/socket.h> /* recv */
59 #include <signal.h> /* sigprocmask, sigwait a.s.o */
60 #endif
61 #ifdef HAVE_EPOLL
62 #include <sys/epoll.h>
63 #endif
64 #ifdef HAVE_KQUEUE
65 #include <sys/types.h> /* needed on freebsd */
66 #include <sys/event.h>
67 #include <sys/time.h>
68 #endif
69 #ifdef HAVE_DEVPOLL
70 #include <sys/devpoll.h>
71 #endif
72 #ifdef HAVE_SELECT
73 /* needed on openbsd for select*/
74 #include <sys/time.h> 
75 #include <sys/types.h> 
76 #include <unistd.h>
77 /* needed according to POSIX for select*/
78 #include <sys/select.h>
79 #endif
80 #include <sys/poll.h>
81 #include <fcntl.h>
82
83 #include "dprint.h"
84
85 #include "poll_types.h" /* poll_types*/
86 #ifdef HAVE_SIGIO_RT
87 #include "pt.h" /* mypid() */
88 #endif
89
90
91 extern int _os_ver; /* os version number, needed to select bugs workarrounds */
92
93
94 #if 0
95 enum fd_types; /* this should be defined from the including file,
96                                   see tcp_main.c for an example, 
97                                   0 has a special meaning: not used/empty*/
98 #endif
99
100 #ifndef FD_TYPE_DEFINED
101 typedef int fd_type;
102 #define FD_TYPE_DEFINED
103 #endif
104
105 /* maps a fd to some other structure; used in almost all cases
106  * except epoll and maybe kqueue or /dev/poll */
107 struct fd_map{
108         int fd;               /* fd no */
109         fd_type type;         /* "data" type */
110         void* data;           /* pointer to the corresponding structure */
111         short events;         /* events we are interested int */
112 };
113
114
115 #ifdef HAVE_KQUEUE
116 #ifndef KQ_CHANGES_ARRAY_SIZE
117 #define KQ_CHANGES_ARRAY_SIZE 256
118
119 #ifdef __OS_netbsd
120 #define KEV_UDATA_CAST (intptr_t)
121 #else
122 #define KEV_UDATA_CAST
123 #endif
124
125 #endif
126 #endif
127
128
129 /* handler structure */
130 struct io_wait_handler{
131 #ifdef HAVE_EPOLL
132         struct epoll_event* ep_array;
133         int epfd; /* epoll ctrl fd */
134 #endif
135 #ifdef HAVE_SIGIO_RT
136         sigset_t sset; /* signal mask for sigio & sigrtmin */
137         int signo;     /* real time signal used */
138 #endif
139 #ifdef HAVE_KQUEUE
140         struct kevent* kq_array;   /* used for the eventlist*/
141         struct kevent* kq_changes; /* used for the changelist */
142         size_t kq_nchanges;
143         size_t kq_changes_size; /* size of the changes array */
144         int kq_fd;
145 #endif
146 #ifdef HAVE_DEVPOLL
147         int dpoll_fd;
148 #endif
149 #ifdef HAVE_SELECT
150         fd_set master_rset; /* read set */
151         fd_set master_wset; /* write set */
152         int max_fd_select; /* maximum select used fd */
153 #endif
154         /* common stuff for POLL, SIGIO_RT and SELECT
155          * since poll support is always compiled => this will always be compiled */
156         struct fd_map* fd_hash;
157         struct pollfd* fd_array;
158         int fd_no; /*  current index used in fd_array */
159         int max_fd_no; /* maximum fd no, is also the size of fd_array,
160                                                        fd_hash  and ep_array*/
161         enum poll_types poll_method;
162         int flags;
163 };
164
165 typedef struct io_wait_handler io_wait_h;
166
167
168 /* get the corresponding fd_map structure pointer */
169 #define get_fd_map(h, fd)               (&(h)->fd_hash[(fd)])
170 /* remove a fd_map structure from the hash; the pointer must be returned
171  * by get_fd_map or hash_fd_map*/
172 #define unhash_fd_map(pfm)      \
173         do{ \
174                 (pfm)->type=0 /*F_NONE */; \
175                 (pfm)->fd=-1; \
176         }while(0)
177
178 /* add a fd_map structure to the fd hash */
179 static inline struct fd_map* hash_fd_map(       io_wait_h* h,
180                                                                                         int fd,
181                                                                                         short events,
182                                                                                         fd_type type,
183                                                                                         void* data)
184 {
185         h->fd_hash[fd].fd=fd;
186         h->fd_hash[fd].events=events;
187         h->fd_hash[fd].type=type;
188         h->fd_hash[fd].data=data;
189         return &h->fd_hash[fd];
190 }
191
192
193
194 #ifdef HANDLE_IO_INLINE
195 /* generic handle io routine, this must be defined in the including file
196  * (faster then registering a callback pointer)
197  *
198  * params:  fm     - pointer to a fd hash entry
199  *          events - combinations of POLLIN, POLLOUT, POLLERR & POLLHUP
200  *          idx    - index in the fd_array (or -1 if not known)
201  * return: -1 on error
202  *          0 on EAGAIN or when by some other way it is known that no more 
203  *            io events are queued on the fd (the receive buffer is empty).
204  *            Usefull to detect when there are no more io events queued for
205  *            sigio_rt, epoll_et, kqueue.
206  *         >0 on successfull read from the fd (when there might be more io
207  *            queued -- the receive buffer might still be non-empty)
208  */
209 inline static int handle_io(struct fd_map* fm, short events, int idx);
210 #else
211 int handle_io(struct fd_map* fm, short events, int idx);
212 #endif
213
214
215
216 #ifdef HAVE_KQUEUE
217 /*
218  * kqueue specific function: register a change
219  * (adds a change to the kevent change array, and if full flushes it first)
220  *
221  * TODO: check if the event already exists in the change list or if it's
222  *       complementary to an event in the list (e.g. EVFILT_WRITE, EV_DELETE
223  *       and EVFILT_WRITE, EV_ADD for the same fd).
224  * returns: -1 on error, 0 on success
225  */
226 static inline int kq_ev_change(io_wait_h* h, int fd, int filter, int flag, 
227                                                                 void* data)
228 {
229         int n;
230         struct timespec tspec;
231
232         if (h->kq_nchanges>=h->kq_changes_size){
233                 /* changes array full ! */
234                 LOG(L_WARN, "WARNING: kq_ev_change: kqueue changes array full"
235                                         " trying to flush...\n");
236                 tspec.tv_sec=0;
237                 tspec.tv_nsec=0;
238 again:
239                 n=kevent(h->kq_fd, h->kq_changes, h->kq_nchanges, 0, 0, &tspec);
240                 if (n==-1){
241                         if (errno==EINTR) goto again;
242                         LOG(L_ERR, "ERROR: io_watch_add: kevent flush changes "
243                                                 " failed: %s [%d]\n", strerror(errno), errno);
244                         return -1;
245                 }
246                 h->kq_nchanges=0; /* changes array is empty */
247         }
248         EV_SET(&h->kq_changes[h->kq_nchanges], fd, filter, flag, 0, 0,
249                         KEV_UDATA_CAST data);
250         h->kq_nchanges++;
251         return 0;
252 }
253 #endif
254
255
256
257 /* generic io_watch_add function
258  * Params:
259  *     h      - pointer to initialized io_wait handle
260  *     fd     - fd to watch
261  *     events - bitmap with the fd events for which the fd should be watched
262  *              (combination of POLLIN and POLLOUT)
263  *     type   - fd type (non 0 value, returned in the call to handle_io)
264  *     data   - pointer/private data returned in the handle_io call
265  * returns 0 on success, -1 on error
266  *
267  * WARNING: handle_io() can be called immediately (from io_watch_add()) so
268  *  make sure that any dependent init. (e.g. data stuff) is made before
269  *  calling io_watch_add
270  *
271  * this version should be faster than pointers to poll_method specific
272  * functions (it avoids functions calls, the overhead being only an extra
273  *  switch())*/
274 inline static int io_watch_add( io_wait_h* h,
275                                                                 int fd,
276                                                                 short events,
277                                                                 fd_type type,
278                                                                 void* data)
279 {
280
281         /* helper macros */
282 #define fd_array_setup(ev) \
283         do{ \
284                 h->fd_array[h->fd_no].fd=fd; \
285                 h->fd_array[h->fd_no].events=(ev); /* useless for select */ \
286                 h->fd_array[h->fd_no].revents=0;     /* useless for select */ \
287         }while(0)
288         
289 #define set_fd_flags(f) \
290         do{ \
291                         flags=fcntl(fd, F_GETFL); \
292                         if (flags==-1){ \
293                                 LOG(L_ERR, "ERROR: io_watch_add: fnctl: GETFL failed:" \
294                                                 " %s [%d]\n", strerror(errno), errno); \
295                                 goto error; \
296                         } \
297                         if (fcntl(fd, F_SETFL, flags|(f))==-1){ \
298                                 LOG(L_ERR, "ERROR: io_watch_add: fnctl: SETFL" \
299                                                         " failed: %s [%d]\n", strerror(errno), errno); \
300                                 goto error; \
301                         } \
302         }while(0)
303         
304         
305         struct fd_map* e;
306         int flags;
307 #ifdef HAVE_EPOLL
308         struct epoll_event ep_event;
309 #endif
310 #ifdef HAVE_DEVPOLL
311         struct pollfd pfd;
312 #endif
313 #if defined(HAVE_SIGIO_RT) || defined (HAVE_EPOLL)
314         int n;
315         int idx;
316         int check_io;
317         struct pollfd pf;
318         
319         check_io=0; /* set to 1 if we need to check for pre-existing queued
320                                    io/data on the fd */
321         idx=-1;
322 #endif
323         e=0;
324         /* sanity checks */
325         if (unlikely(fd==-1)){
326                 LOG(L_CRIT, "BUG: io_watch_add: fd is -1!\n");
327                 goto error;
328         }
329         if (unlikely((events&(POLLIN|POLLOUT))==0)){
330                 LOG(L_CRIT, "BUG: io_watch_add: invalid events: 0x%0x\n", events);
331                 goto error;
332         }
333         /* check if not too big */
334         if (unlikely(h->fd_no>=h->max_fd_no)){
335                 LOG(L_CRIT, "ERROR: io_watch_add: maximum fd number exceeded:"
336                                 " %d/%d\n", h->fd_no, h->max_fd_no);
337                 goto error;
338         }
339         DBG("DBG: io_watch_add(%p, %d, %d, %p), fd_no=%d\n",
340                         h, fd, type, data, h->fd_no);
341         /*  hash sanity check */
342         e=get_fd_map(h, fd);
343         if (unlikely(e && (e->type!=0 /*F_NONE*/))){
344                 LOG(L_ERR, "ERROR: io_watch_add: trying to overwrite entry %d"
345                                 " in the hash(%d, %d, %p) with (%d, %d, %p)\n",
346                                 fd, e->fd, e->type, e->data, fd, type, data);
347                 goto error;
348         }
349         
350         if (unlikely((e=hash_fd_map(h, fd, events, type, data))==0)){
351                 LOG(L_ERR, "ERROR: io_watch_add: failed to hash the fd %d\n", fd);
352                 goto error;
353         }
354         switch(h->poll_method){ /* faster then pointer to functions */
355                 case POLL_POLL:
356                         fd_array_setup(events);
357                         set_fd_flags(O_NONBLOCK);
358                         break;
359 #ifdef HAVE_SELECT
360                 case POLL_SELECT:
361                         fd_array_setup(events);
362                         if (likely(events & POLLIN))
363                                 FD_SET(fd, &h->master_rset);
364                         if (unlikely(events & POLLOUT))
365                                 FD_SET(fd, &h->master_wset);
366                         if (h->max_fd_select<fd) h->max_fd_select=fd;
367                         break;
368 #endif
369 #ifdef HAVE_SIGIO_RT
370                 case POLL_SIGIO_RT:
371                         fd_array_setup(events);
372                         /* re-set O_ASYNC might be needed, if not done from 
373                          * io_watch_del (or if somebody wants to add a fd which has
374                          * already O_ASYNC/F_SETSIG set on a duplicate)
375                          */
376                         /* set async & signal */
377                         if (fcntl(fd, F_SETOWN, my_pid())==-1){
378                                 LOG(L_ERR, "ERROR: io_watch_add: fnctl: SETOWN"
379                                 " failed: %s [%d]\n", strerror(errno), errno);
380                                 goto error;
381                         }
382                         if (fcntl(fd, F_SETSIG, h->signo)==-1){
383                                 LOG(L_ERR, "ERROR: io_watch_add: fnctl: SETSIG"
384                                         " failed: %s [%d]\n", strerror(errno), errno);
385                                 goto error;
386                         }
387                         /* set both non-blocking and async */
388                         set_fd_flags(O_ASYNC| O_NONBLOCK);
389 #ifdef EXTRA_DEBUG
390                         DBG("io_watch_add: sigio_rt on f %d, signal %d to pid %d\n",
391                                         fd,  h->signo, my_pid());
392 #endif
393                         /* empty socket receive buffer, if buffer is already full
394                          * no more space to put packets
395                          * => no more signals are ever generated
396                          * also when moving fds, the freshly moved fd might have
397                          *  already some bytes queued, we want to get them now
398                          *  and not later -- andrei */
399                         idx=h->fd_no;
400                         check_io=1;
401                         break;
402 #endif
403 #ifdef HAVE_EPOLL
404                 case POLL_EPOLL_LT:
405                         ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
406                                                          (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
407                         ep_event.data.ptr=e;
408 again1:
409                         n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
410                         if (unlikely(n==-1)){
411                                 if (errno==EAGAIN) goto again1;
412                                 LOG(L_ERR, "ERROR: io_watch_add: epoll_ctl failed: %s [%d]\n",
413                                         strerror(errno), errno);
414                                 goto error;
415                         }
416                         break;
417                 case POLL_EPOLL_ET:
418                         set_fd_flags(O_NONBLOCK);
419                         ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) )  |
420                                                          (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
421                                                           EPOLLET;
422                         ep_event.data.ptr=e;
423 again2:
424                         n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
425                         if (unlikely(n==-1)){
426                                 if (errno==EAGAIN) goto again2;
427                                 LOG(L_ERR, "ERROR: io_watch_add: epoll_ctl failed: %s [%d]\n",
428                                         strerror(errno), errno);
429                                 goto error;
430                         }
431                         idx=-1;
432                         check_io=1;
433                         break;
434 #endif
435 #ifdef HAVE_KQUEUE
436                 case POLL_KQUEUE:
437                         if (likely( events & POLLINT)){
438                                 if (unlikely(kq_ev_change(h, fd, EVFILT_READ, EV_ADD, e)==-1))
439                                 goto error;
440                         }
441                         if (unlikely( events & POLLOUT)){
442                                 if (unlikely(kq_ev_change(h, fd, EVFILT_WRITE, EV_ADD, e)==-1))
443                                 goto error;
444                         }
445                         break;
446 #endif
447 #ifdef HAVE_DEVPOLL
448                 case POLL_DEVPOLL:
449                         pfd.fd=fd;
450                         pfd.events=events;
451                         pfd.revents=0;
452 again_devpoll:
453                         if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){
454                                 if (errno==EAGAIN) goto again_devpoll;
455                                 LOG(L_ERR, "ERROR: io_watch_add: /dev/poll write failed:"
456                                                         "%s [%d]\n", strerror(errno), errno);
457                                 goto error;
458                         }
459                         break;
460 #endif
461                         
462                 default:
463                         LOG(L_CRIT, "BUG: io_watch_add: no support for poll method "
464                                         " %s (%d)\n", poll_method_str[h->poll_method],
465                                         h->poll_method);
466                         goto error;
467         }
468         
469         h->fd_no++; /* "activate" changes, for epoll/kqueue/devpoll it
470                                    has only informative value */
471 #if defined(HAVE_SIGIO_RT) || defined (HAVE_EPOLL)
472         if (check_io){
473                 /* handle possible pre-existing events */
474                 pf.fd=fd;
475                 pf.events=events;
476 check_io_again:
477                 while(e->type && ((n=poll(&pf, 1, 0))>0) && 
478                                 (handle_io(e, pf.revents, idx)>0) &&
479                                 (pf.revents & e->events));
480                 if (unlikely(e->type && (n==-1))){
481                         if (errno==EINTR) goto check_io_again;
482                         LOG(L_ERR, "ERROR: io_watch_add: check_io poll: %s [%d]\n",
483                                                 strerror(errno), errno);
484                 }
485         }
486 #endif
487         return 0;
488 error:
489         if (e) unhash_fd_map(e);
490         return -1;
491 #undef fd_array_setup
492 #undef set_fd_flags 
493 }
494
495
496
497 #define IO_FD_CLOSING 16
498 /* parameters:    h - handler 
499  *               fd - file descriptor
500  *            index - index in the fd_array if known, -1 if not
501  *                    (if index==-1 fd_array will be searched for the
502  *                     corresponding fd* entry -- slower but unavoidable in 
503  *                     some cases). index is not used (no fd_array) for epoll,
504  *                     /dev/poll and kqueue
505  *            flags - optimization flags, e.g. IO_FD_CLOSING, the fd was 
506  *                    or will shortly be closed, in some cases we can avoid
507  *                    extra remove operations (e.g.: epoll, kqueue, sigio)
508  * returns 0 if ok, -1 on error */
509 inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags)
510 {
511         
512 #define fix_fd_array \
513         do{\
514                         if (unlikely(idx==-1)){ \
515                                 /* fix idx if -1 and needed */ \
516                                 for (idx=0; (idx<h->fd_no) && \
517                                                         (h->fd_array[idx].fd!=fd); idx++); \
518                         } \
519                         if (likely(idx<h->fd_no)){ \
520                                 memmove(&h->fd_array[idx], &h->fd_array[idx+1], \
521                                         (h->fd_no-(idx+1))*sizeof(*(h->fd_array))); \
522                         } \
523         }while(0)
524         
525         struct fd_map* e;
526         int events;
527 #ifdef HAVE_EPOLL
528         int n;
529         struct epoll_event ep_event;
530 #endif
531 #ifdef HAVE_DEVPOLL
532         struct pollfd pfd;
533 #endif
534 #ifdef HAVE_SIGIO_RT
535         int fd_flags;
536 #endif
537         
538         if (unlikely((fd<0) || (fd>=h->max_fd_no))){
539                 LOG(L_CRIT, "BUG: io_watch_del: invalid fd %d, not in [0, %d) \n",
540                                                 fd, h->fd_no);
541                 goto error;
542         }
543         DBG("DBG: io_watch_del (%p, %d, %d, 0x%x) fd_no=%d called\n",
544                         h, fd, idx, flags, h->fd_no);
545         e=get_fd_map(h, fd);
546         /* more sanity checks */
547         if (unlikely(e==0)){
548                 LOG(L_CRIT, "BUG: io_watch_del: no corresponding hash entry for %d\n",
549                                         fd);
550                 goto error;
551         }
552         if (unlikely(e->type==0 /*F_NONE*/)){
553                 LOG(L_ERR, "ERROR: io_watch_del: trying to delete already erased"
554                                 " entry %d in the hash(%d, %d, %p) )\n",
555                                 fd, e->fd, e->type, e->data);
556                 goto error;
557         }
558         events=e->events;
559         unhash_fd_map(e);
560         
561         switch(h->poll_method){
562                 case POLL_POLL:
563                         fix_fd_array;
564                         break;
565 #ifdef HAVE_SELECT
566                 case POLL_SELECT:
567                         if (likely(events & POLLIN))
568                                 FD_CLR(fd, &h->master_rset);
569                         if (unlikely(events & POLLOUT))
570                                 FD_CLR(fd, &h->master_wset);
571                         if (unlikely(h->max_fd_select && (h->max_fd_select==fd)))
572                                 /* we don't know the prev. max, so we just decrement it */
573                                 h->max_fd_select--; 
574                         fix_fd_array;
575                         break;
576 #endif
577 #ifdef HAVE_SIGIO_RT
578                 case POLL_SIGIO_RT:
579                         fix_fd_array;
580                         /* the O_ASYNC flag must be reset all the time, the fd
581                          *  can be changed only if  O_ASYNC is reset (if not and
582                          *  the fd is a duplicate, you will get signals from the dup. fd
583                          *  and not from the original, even if the dup. fd was closed
584                          *  and the signals re-set on the original) -- andrei
585                          */
586                         /*if (!(flags & IO_FD_CLOSING)){*/
587                                 /* reset ASYNC */
588                                 fd_flags=fcntl(fd, F_GETFL); 
589                                 if (unlikely(fd_flags==-1)){ 
590                                         LOG(L_ERR, "ERROR: io_watch_del: fnctl: GETFL failed:" 
591                                                         " %s [%d]\n", strerror(errno), errno); 
592                                         goto error; 
593                                 } 
594                                 if (unlikely(fcntl(fd, F_SETFL, fd_flags&(~O_ASYNC))==-1)){ 
595                                         LOG(L_ERR, "ERROR: io_watch_del: fnctl: SETFL" 
596                                                                 " failed: %s [%d]\n", strerror(errno), errno); 
597                                         goto error; 
598                                 } 
599                         break;
600 #endif
601 #ifdef HAVE_EPOLL
602                 case POLL_EPOLL_LT:
603                 case POLL_EPOLL_ET:
604                         /* epoll doesn't seem to automatically remove sockets,
605                          * if the socket is a duplicate/moved and the original
606                          * is still open. The fd is removed from the epoll set
607                          * only when the original (and all the  copies?) is/are 
608                          * closed. This is probably a bug in epoll. --andrei */
609 #ifdef EPOLL_NO_CLOSE_BUG
610                         if (!(flags & IO_FD_CLOSING)){
611 #endif
612 again_epoll:
613                                 n=epoll_ctl(h->epfd, EPOLL_CTL_DEL, fd, &ep_event);
614                                 if (unlikely(n==-1)){
615                                         if (errno==EAGAIN) goto again_epoll;
616                                         LOG(L_ERR, "ERROR: io_watch_del: removing fd from epoll "
617                                                         "list failed: %s [%d]\n", strerror(errno), errno);
618                                         goto error;
619                                 }
620 #ifdef EPOLL_NO_CLOSE_BUG
621                         }
622 #endif
623                         break;
624 #endif
625 #ifdef HAVE_KQUEUE
626                 case POLL_KQUEUE:
627                         if (!(flags & IO_FD_CLOSING)){
628                                 if (likely(events & POLLIN)){
629                                         if (unlikely(kq_ev_change(h, fd, EVFILT_READ,
630                                                                                                         EV_DELETE, 0) ==-1)){
631                                                 /* try to delete the write filter anyway */
632                                                 if (events & POLLOUT){
633                                                         kq_ev_change(h, fd, EVFILT_WRITE, EV_DELETE, 0);
634                                                 }
635                                                 goto error;
636                                         }
637                                 }
638                                 if (unlikely(events & POLLOUT)){
639                                         if (unlikely(kq_ev_change(h, fd, EVFILT_WRITE,
640                                                                                                         EV_DELETE, 0) ==-1))
641                                                 goto error;
642                                 }
643                         }
644                         break;
645 #endif
646 #ifdef HAVE_DEVPOLL
647                 case POLL_DEVPOLL:
648                                 /* for /dev/poll the closed fds _must_ be removed
649                                    (they are not removed automatically on close()) */
650                                 pfd.fd=fd;
651                                 pfd.events=POLLREMOVE;
652                                 pfd.revents=0;
653 again_devpoll:
654                                 if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){
655                                         if (errno==EINTR) goto again_devpoll;
656                                         LOG(L_ERR, "ERROR: io_watch_del: removing fd from "
657                                                                 "/dev/poll failed: %s [%d]\n", 
658                                                                 strerror(errno), errno);
659                                         goto error;
660                                 }
661                                 break;
662 #endif
663                 default:
664                         LOG(L_CRIT, "BUG: io_watch_del: no support for poll method "
665                                         " %s (%d)\n", poll_method_str[h->poll_method], 
666                                         h->poll_method);
667                         goto error;
668         }
669         h->fd_no--;
670         return 0;
671 error:
672         return -1;
673 #undef fix_fd_array
674 }
675
676
677
678 /* parameters:    h - handler 
679  *               fd - file descriptor
680  *           events - new events to watch for
681  *              idx - index in the fd_array if known, -1 if not
682  *                    (if index==-1 fd_array will be searched for the
683  *                     corresponding fd* entry -- slower but unavoidable in 
684  *                     some cases). index is not used (no fd_array) for epoll,
685  *                     /dev/poll and kqueue
686  * returns 0 if ok, -1 on error */
687 inline static int io_watch_chg(io_wait_h* h, int fd, short events, int idx )
688 {
689         
690 #define fd_array_chg(ev) \
691         do{\
692                         if (unlikely(idx==-1)){ \
693                                 /* fix idx if -1 and needed */ \
694                                 for (idx=0; (idx<h->fd_no) && \
695                                                         (h->fd_array[idx].fd!=fd); idx++); \
696                         } \
697                         if (likely(idx<h->fd_no)){ \
698                                 h->fd_array[idx].events=(ev); \
699                         } \
700         }while(0)
701         
702         struct fd_map* e;
703         int add_events;
704         int del_events;
705 #ifdef HAVE_EPOLL
706         int n;
707         struct epoll_event ep_event;
708 #endif
709 #ifdef HAVE_DEVPOLL
710         struct pollfd pfd;
711 #endif
712         
713         if (unlikely((fd<0) || (fd>=h->max_fd_no))){
714                 LOG(L_CRIT, "BUG: io_watch_chg: invalid fd %d, not in [0, %d) \n",
715                                                 fd, h->fd_no);
716                 goto error;
717         }
718         if (unlikely((events&(POLLIN|POLLOUT))==0)){
719                 LOG(L_CRIT, "BUG: io_watch_chg: invalid events: 0x%0x\n", events);
720                 goto error;
721         }
722         DBG("DBG: io_watch_chg (%p, %d, 0x%x, 0x%x) fd_no=%d called\n",
723                         h, fd, events, idx, h->fd_no);
724         e=get_fd_map(h, fd);
725         /* more sanity checks */
726         if (unlikely(e==0)){
727                 LOG(L_CRIT, "BUG: io_watch_chg: no corresponding hash entry for %d\n",
728                                         fd);
729                 goto error;
730         }
731         if (unlikely(e->type==0 /*F_NONE*/)){
732                 LOG(L_ERR, "ERROR: io_watch_chg: trying to change an already erased"
733                                 " entry %d in the hash(%d, %d, %p) )\n",
734                                 fd, e->fd, e->type, e->data);
735                 goto error;
736         }
737         
738         add_events=events & ~e->events;
739         del_events=e->events & ~events;
740         e->events=events;
741         switch(h->poll_method){
742                 case POLL_POLL:
743                         fd_array_chg(events);
744                         break;
745 #ifdef HAVE_SELECT
746                 case POLL_SELECT:
747                         fd_array_chg(events);
748                         if (unlikely(del_events & POLLIN))
749                                 FD_CLR(fd, &h->master_rset);
750                         else if (unlikely(add_events & POLLIN))
751                                 FD_SET(fd, &h->master_rset);
752                         if (likely(del_events & POLLOUT))
753                                 FD_CLR(fd, &h->master_wset);
754                         else if (likely(add_events & POLLOUT))
755                                 FD_SET(fd, &h->master_wset);
756                         break;
757 #endif
758 #ifdef HAVE_SIGIO_RT
759                 case POLL_SIGIO_RT:
760                         fd_array_chg(events);
761                         break;
762 #endif
763 #ifdef HAVE_EPOLL
764                 case POLL_EPOLL_LT:
765                                 ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
766                                                                  (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
767                                 ep_event.data.ptr=e;
768 again_epoll_lt:
769                                 n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
770                                 if (unlikely(n==-1)){
771                                         if (errno==EAGAIN) goto again_epoll_lt;
772                                         LOG(L_ERR, "ERROR: io_watch_chg: modifying epoll events"
773                                                         " failed: %s [%d]\n", strerror(errno), errno);
774                                         goto error;
775                                 }
776                         break;
777                 case POLL_EPOLL_ET:
778                                 ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
779                                                                  (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
780                                                                  EPOLLET;
781                                 ep_event.data.ptr=e;
782 again_epoll_et:
783                                 n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
784                                 if (unlikely(n==-1)){
785                                         if (errno==EAGAIN) goto again_epoll_et;
786                                         LOG(L_ERR, "ERROR: io_watch_chg: modifying epoll events"
787                                                         " failed: %s [%d]\n", strerror(errno), errno);
788                                         goto error;
789                                 }
790                         break;
791 #endif
792 #ifdef HAVE_KQUEUE
793                 case POLL_KQUEUE:
794                         if (unlikely(del_events & POLLIN)){
795                                 if (unlikely(kq_ev_change(h, fd, EVFILT_READ,
796                                                                                                                 EV_DELETE, 0) ==-1))
797                                                 goto error;
798                         }else if (unlikely(add_events & POLLIN)){
799                                 if (unlikely(kq_ev_change(h, fd, EVFILT_READ, EV_ADD, e) ==-1))
800                                         goto error;
801                         }
802                         if (likely(del_events & POLLOUT)){
803                                 if (unlikely(kq_ev_change(h, fd, EVFILT_WRITE,
804                                                                                                                 EV_DELETE, 0) ==-1))
805                                                 goto error;
806                         }else if (likely(add_events & POLLOUT)){
807                                 if (unlikely(kq_ev_change(h, fd, EVFILT_WRITE, EV_ADD, e)==-1))
808                                         goto error;
809                         }
810                         break;
811 #endif
812 #ifdef HAVE_DEVPOLL
813                 case POLL_DEVPOLL:
814                                 /* for /dev/poll the closed fds _must_ be removed
815                                    (they are not removed automatically on close()) */
816                                 pfd.fd=fd;
817                                 pfd.events=POLLREMOVE;
818                                 pfd.revents=0;
819 again_devpoll1:
820                                 if (unlikely(write(h->dpoll_fd, &pfd, sizeof(pfd))==-1)){
821                                         if (errno==EINTR) goto again_devpoll1;
822                                         LOG(L_ERR, "ERROR: io_watch_chg: removing fd from "
823                                                                 "/dev/poll failed: %s [%d]\n", 
824                                                                 strerror(errno), errno);
825                                         goto error;
826                                 }
827 again_devpoll2:
828                                 pfd.events=events;
829                                 pfd.revents=0;
830                                 if (unlikely(write(h->dpoll_fd, &pfd, sizeof(pfd))==-1)){
831                                         if (errno==EINTR) goto again_devpoll2;
832                                         LOG(L_ERR, "ERROR: io_watch_chg: re-adding fd to "
833                                                                 "/dev/poll failed: %s [%d]\n", 
834                                                                 strerror(errno), errno);
835                                         goto error;
836                                 }
837                                 break;
838 #endif
839                 default:
840                         LOG(L_CRIT, "BUG: io_watch_chg: no support for poll method "
841                                         " %s (%d)\n", poll_method_str[h->poll_method], 
842                                         h->poll_method);
843                         goto error;
844         }
845         return 0;
846 error:
847         return -1;
848 #undef fix_fd_array
849 }
850
851 /* io_wait_loop_x style function 
852  * wait for io using poll()
853  * params: h      - io_wait handle
854  *         t      - timeout in s
855  *         repeat - if !=0 handle_io will be called until it returns <=0
856  * returns: number of IO events handled on success (can be 0), -1 on error
857  */
858 inline static int io_wait_loop_poll(io_wait_h* h, int t, int repeat)
859 {
860         int n, r;
861         int ret;
862         struct fd_map* fm;
863 again:
864                 ret=n=poll(h->fd_array, h->fd_no, t*1000);
865                 if (n==-1){
866                         if (errno==EINTR) goto again; /* signal, ignore it */
867                         else{
868                                 LOG(L_ERR, "ERROR:io_wait_loop_poll: poll: %s [%d]\n",
869                                                 strerror(errno), errno);
870                                 goto error;
871                         }
872                 }
873                 for (r=0; (r<h->fd_no) && n; r++){
874                         fm=get_fd_map(h, h->fd_array[r].fd);
875                         if (h->fd_array[r].revents & (fm->events|POLLERR|POLLHUP)){
876                                 n--;
877                                 /* sanity checks */
878                                 if (unlikely((h->fd_array[r].fd >= h->max_fd_no)||
879                                                                 (h->fd_array[r].fd < 0))){
880                                         LOG(L_CRIT, "BUG: io_wait_loop_poll: bad fd %d "
881                                                         "(no in the 0 - %d range)\n",
882                                                         h->fd_array[r].fd, h->max_fd_no);
883                                         /* try to continue anyway */
884                                         h->fd_array[r].events=0; /* clear the events */
885                                         continue;
886                                 }
887                                 /* repeat handle_io if repeat, fd still watched (not deleted
888                                  *  inside handle_io), handle_io returns that there's still
889                                  *  IO and the fd is still watched for the triggering event */
890                                 while(fm->type && 
891                                                 (handle_io(fm, h->fd_array[r].revents, r) > 0) &&
892                                                 repeat &&
893                                                 (fm->events & h->fd_array[r].revents) );
894                         }
895                 }
896 error:
897         return ret;
898 }
899
900
901
902 #ifdef HAVE_SELECT
903 /* wait for io using select */
904 inline static int io_wait_loop_select(io_wait_h* h, int t, int repeat)
905 {
906         fd_set sel_rset;
907         fd_set sel_wset;
908         int n, ret;
909         struct timeval timeout;
910         int r;
911         struct fd_map* fm;
912         int revents;
913         
914 again:
915                 sel_rset=h->master_rset;
916                 sel_wset=h->master_wset;
917                 timeout.tv_sec=t;
918                 timeout.tv_usec=0;
919                 ret=n=select(h->max_fd_select+1, &sel_rset, &sel_wset, 0, &timeout);
920                 if (n<0){
921                         if (errno==EINTR) goto again; /* just a signal */
922                         LOG(L_ERR, "ERROR: io_wait_loop_select: select: %s [%d]\n",
923                                         strerror(errno), errno);
924                         n=0;
925                         /* continue */
926                 }
927                 /* use poll fd array */
928                 for(r=0; (r<h->max_fd_no) && n; r++){
929                         revents=0;
930                         if (likely(FD_ISSET(h->fd_array[r].fd, &sel_rset)))
931                                 revents|=POLLIN;
932                         if (unlikely(FD_ISSET(h->fd_array[r].fd, &sel_wset)))
933                                 revents|=POLLOUT;
934                         if (likely(revents)){
935                                 fm=get_fd_map(h, h->fd_array[r].fd);
936                                 while(fm->type && (fm->events & revents) && 
937                                                 (handle_io(fm, revents, r)>0) && repeat);
938                                 n--;
939                         }
940                 };
941         return ret;
942 }
943 #endif
944
945
946
947 #ifdef HAVE_EPOLL
948 inline static int io_wait_loop_epoll(io_wait_h* h, int t, int repeat)
949 {
950         int n, r;
951         struct fd_map* fm;
952         int revents;
953         
954 again:
955                 n=epoll_wait(h->epfd, h->ep_array, h->fd_no, t*1000);
956                 if (unlikely(n==-1)){
957                         if (errno==EINTR) goto again; /* signal, ignore it */
958                         else{
959                                 LOG(L_ERR, "ERROR:io_wait_loop_epoll: "
960                                                 "epoll_wait(%d, %p, %d, %d): %s [%d]\n", 
961                                                 h->epfd, h->ep_array, h->fd_no, t*1000,
962                                                 strerror(errno), errno);
963                                 goto error;
964                         }
965                 }
966 #if 0
967                 if (n>1){
968                         for(r=0; r<n; r++){
969                                 LOG(L_ERR, "WARNING: ep_array[%d]= %x, %p\n",
970                                                 r, h->ep_array[r].events, h->ep_array[r].data.ptr);
971                         }
972                 }
973 #endif
974                 for (r=0; r<n; r++){
975                         revents= (POLLIN & (!(h->ep_array[r].events & EPOLLIN)-1)) |
976                                          (POLLOUT & (!(h->ep_array[r].events & EPOLLOUT)-1)) |
977                                          (POLLERR & (!(h->ep_array[r].events & EPOLLERR)-1)) |
978                                          (POLLHUP & (!(h->ep_array[r].events & EPOLLHUP)-1));
979                         if (likely(revents)){
980                                 fm=(struct fd_map*)h->ep_array[r].data.ptr;
981                                 while(fm->type && (fm->events & revents) && 
982                                                 (handle_io(fm, revents, -1)>0) && repeat);
983                         }else{
984                                 LOG(L_ERR, "ERROR:io_wait_loop_epoll: unexpected event %x"
985                                                         " on %d/%d, data=%p\n", h->ep_array[r].events,
986                                                         r+1, n, h->ep_array[r].data.ptr);
987                         }
988                 }
989 error:
990         return n;
991 }
992 #endif
993
994
995
996 #ifdef HAVE_KQUEUE
997 inline static int io_wait_loop_kqueue(io_wait_h* h, int t, int repeat)
998 {
999         int n, r;
1000         struct timespec tspec;
1001         struct fd_map* fm;
1002         
1003         tspec.tv_sec=t;
1004         tspec.tv_nsec=0;
1005 again:
1006                 n=kevent(h->kq_fd, h->kq_changes, h->kq_nchanges,  h->kq_array,
1007                                         h->fd_no, &tspec);
1008                 if (unlikely(n==-1)){
1009                         if (errno==EINTR) goto again; /* signal, ignore it */
1010                         else{
1011                                 LOG(L_ERR, "ERROR: io_wait_loop_kqueue: kevent:"
1012                                                 " %s [%d]\n", strerror(errno), errno);
1013                                 goto error;
1014                         }
1015                 }
1016                 h->kq_nchanges=0; /* reset changes array */
1017                 for (r=0; r<n; r++){
1018 #ifdef EXTRA_DEBUG
1019                         DBG("DBG: kqueue: event %d/%d: fd=%d, udata=%lx, flags=0x%x\n",
1020                                         r, n, h->kq_array[r].ident, (long)h->kq_array[r].udata,
1021                                         h->kq_array[r].flags);
1022 #endif
1023 #if 0
1024                         if (unlikely(h->kq_array[r].flags & EV_ERROR)){
1025                                 /* error in changes: we ignore it, it can be caused by
1026                                    trying to remove an already closed fd: race between
1027                                    adding something to the changes array, close() and
1028                                    applying the changes */
1029                                 LOG(L_INFO, "INFO: io_wait_loop_kqueue: kevent error on "
1030                                                         "fd %d: %s [%ld]\n", h->kq_array[r].ident,
1031                                                         strerror(h->kq_array[r].data),
1032                                                         (long)h->kq_array[r].data);
1033                         }else{ 
1034 #endif
1035                                 fm=(struct fd_map*)h->kq_array[r].udata;
1036                                 if (likely(h->kq_array[r].filter==EVFILT_READ)){
1037                                         revents=POLLIN | 
1038                                                 (((int)!(h->kq_array[r].flags & EV_EOF)-1)&POLLHUP);
1039                                         while(fm->type && (fm->events & revents) && 
1040                                                         (handle_io(fm, revents, -1)>0) && repeat);
1041                                 }else if (h->kq_array[r].filter==EVFILT_WRITE){
1042                                         revents=POLLOUT | 
1043                                                 (((int)!(h->kq_array[r].flags & EV_EOF)-1)&POLLHUP);
1044                                         while(fm->type && (fm->events & revents) && 
1045                                                         (handle_io(fm, revents, -1)>0) && repeat);
1046                                 }
1047                         }
1048                 }
1049 error:
1050         return n;
1051 }
1052 #endif
1053
1054
1055
1056 #ifdef HAVE_SIGIO_RT
1057 /* sigio rt version has no repeat (it doesn't make sense)*/
1058 inline static int io_wait_loop_sigio_rt(io_wait_h* h, int t)
1059 {
1060         int n;
1061         int ret;
1062         struct timespec ts;
1063         siginfo_t siginfo;
1064         int sigio_band;
1065         int sigio_fd;
1066         struct fd_map* fm;
1067         int revents;
1068         
1069         
1070         ret=1; /* 1 event per call normally */
1071         ts.tv_sec=t;
1072         ts.tv_nsec=0;
1073         if (unlikely(!sigismember(&h->sset, h->signo) ||
1074                                         !sigismember(&h->sset, SIGIO))) {
1075                 LOG(L_CRIT, "BUG: io_wait_loop_sigio_rt: the signal mask"
1076                                 " is not properly set!\n");
1077                 goto error;
1078         }
1079
1080 again:
1081         n=sigtimedwait(&h->sset, &siginfo, &ts);
1082         if (unlikely(n==-1)){
1083                 if (errno==EINTR) goto again; /* some other signal, ignore it */
1084                 else if (errno==EAGAIN){ /* timeout */
1085                         ret=0;
1086                         goto end;
1087                 }else{
1088                         LOG(L_ERR, "ERROR: io_wait_loop_sigio_rt: sigtimed_wait"
1089                                         " %s [%d]\n", strerror(errno), errno);
1090                         goto error;
1091                 }
1092         }
1093         if (likely(n!=SIGIO)){
1094 #ifdef SIGINFO64_WORKARROUND
1095                 /* on linux siginfo.si_band is defined as long in userspace
1096                  * and as int in kernel (< 2.6.5) => on 64 bits things will break!
1097                  * (si_band will include si_fd, and si_fd will contain
1098                  *  garbage).
1099                  *  see /usr/src/linux/include/asm-generic/siginfo.h and
1100                  *      /usr/include/bits/siginfo.h
1101                  *  On newer kernels this is fixed (si_band is long in the kernel too).
1102                  * -- andrei */
1103                 if  ((_os_ver<0x020605) && (sizeof(siginfo.si_band)>sizeof(int))){
1104                         sigio_band=*((int*)(void*)&siginfo.si_band);
1105                         sigio_fd=*(((int*)(void*)&siginfo.si_band)+1);
1106                 }else
1107 #endif
1108                 {
1109                         sigio_band=siginfo.si_band;
1110                         sigio_fd=siginfo.si_fd;
1111                 }
1112                 if (unlikely(siginfo.si_code==SI_SIGIO)){
1113                         /* old style, we don't know the event (linux 2.2.?) */
1114                         LOG(L_WARN, "WARNING: io_wait_loop_sigio_rt: old style sigio"
1115                                         " interface\n");
1116                         fm=get_fd_map(h, sigio_fd);
1117                         /* we can have queued signals generated by fds not watched
1118                          * any more, or by fds in transition, to a child => ignore them*/
1119                         if (fm->type)
1120                                 handle_io(fm, POLLIN|POLLOUT, -1);
1121                 }else{
1122 #ifdef EXTRA_DEBUG
1123                         DBG("io_wait_loop_sigio_rt: siginfo: signal=%d (%d),"
1124                                         " si_code=%d, si_band=0x%x,"
1125                                         " si_fd=%d\n",
1126                                         siginfo.si_signo, n, siginfo.si_code, 
1127                                         (unsigned)sigio_band,
1128                                         sigio_fd);
1129 #endif
1130                         /* on some errors (e.g. when receving TCP RST), sigio_band will
1131                          * be set to 0x08 (undocumented, no corresp. POLL_xx), so better
1132                          * catch all events --andrei */
1133                         if (likely(sigio_band)/*&(POLL_IN|POLL_ERR|POLL_HUP)*/){
1134                                 fm=get_fd_map(h, sigio_fd);
1135                                 revents=(POLLIN & (!(sigio_band & POLL_IN)-1)) |
1136                                                 (POLLOUT & (!(sigio_band & POLL_OUT)-1)) |
1137                                                 (POLLERR & (!(sigio_band & POLL_ERR)-1)) |
1138                                                 (POLLHUP & (!(sigio_band & POLL_HUP)-1));
1139                                 /* we can have queued signals generated by fds not watched
1140                                  * any more, or by fds in transition, to a child 
1141                                  * => ignore them */
1142                                 if (fm->type && (fm->events & revents))
1143                                         handle_io(fm, revents, -1);
1144                                 else
1145                                         LOG(L_ERR, "WARNING: io_wait_loop_sigio_rt: ignoring event"
1146                                                         " %x on fd %d (fm->fd=%d, fm->data=%p)\n",
1147                                                         sigio_band, sigio_fd, fm->fd, fm->data);
1148                         }else{
1149                                 LOG(L_ERR, "ERROR: io_wait_loop_sigio_rt: unexpected event"
1150                                                         " on fd %d: %x\n", sigio_fd, sigio_band);
1151                         }
1152                 }
1153         }else{
1154                 /* signal queue overflow 
1155                  * TODO: increase signal queue size: 2.4x /proc/.., 2.6x -rlimits */
1156                 LOG(L_WARN, "WARNING: io_wait_loop_sigio_rt: signal queue overflowed"
1157                                         "- falling back to poll\n");
1158                 /* clear real-time signal queue
1159                  * both SIG_IGN and SIG_DFL are needed , it doesn't work
1160                  * only with SIG_DFL  */
1161                 if (signal(h->signo, SIG_IGN)==SIG_ERR){
1162                         LOG(L_CRIT, "BUG: do_poll: couldn't reset signal to IGN\n");
1163                 }
1164                 
1165                 if (signal(h->signo, SIG_DFL)==SIG_ERR){
1166                         LOG(L_CRIT, "BUG: do_poll: couldn't reset signal to DFL\n");
1167                 }
1168                 /* falling back to normal poll */
1169                 ret=io_wait_loop_poll(h, -1, 1);
1170         }
1171 end:
1172         return ret;
1173 error:
1174         return -1;
1175 }
1176 #endif
1177
1178
1179
1180 #ifdef HAVE_DEVPOLL
1181 inline static int io_wait_loop_devpoll(io_wait_h* h, int t, int repeat)
1182 {
1183         int n, r;
1184         int ret;
1185         struct dvpoll dpoll;
1186         struct fd_map* fm;
1187
1188                 dpoll.dp_timeout=t*1000;
1189                 dpoll.dp_nfds=h->fd_no;
1190                 dpoll.dp_fds=h->fd_array;
1191 again:
1192                 ret=n=ioctl(h->dpoll_fd, DP_POLL, &dpoll);
1193                 if (unlikely(n==-1)){
1194                         if (errno==EINTR) goto again; /* signal, ignore it */
1195                         else{
1196                                 LOG(L_ERR, "ERROR:io_wait_loop_devpoll: ioctl: %s [%d]\n",
1197                                                 strerror(errno), errno);
1198                                 goto error;
1199                         }
1200                 }
1201                 for (r=0; r< n; r++){
1202                         if (h->fd_array[r].revents & (POLLNVAL|POLLERR)){
1203                                 LOG(L_ERR, "ERROR: io_wait_loop_devpoll: pollinval returned"
1204                                                         " for fd %d, revents=%x\n",
1205                                                         h->fd_array[r].fd, h->fd_array[r].revents);
1206                         }
1207                         /* POLLIN|POLLHUP just go through */
1208                         fm=get_fd_map(h, h->fd_array[r].fd);
1209                         while(fm->type && (fm->events & h->fd_array[r].revents) &&
1210                                         (handle_io(fm, h->fd_array[r].revents, r) > 0) && repeat);
1211                 }
1212 error:
1213         return ret;
1214 }
1215 #endif
1216
1217
1218
1219 /* init */
1220
1221
1222 /* initializes the static vars/arrays
1223  * params:      h - pointer to the io_wait_h that will be initialized
1224  *         max_fd - maximum allowed fd number
1225  *         poll_m - poll method (0 for automatic best fit)
1226  */
1227 int init_io_wait(io_wait_h* h, int max_fd, enum poll_types poll_method);
1228
1229 /* destroys everything init_io_wait allocated */
1230 void destroy_io_wait(io_wait_h* h);
1231
1232
1233 #endif