Coverage Report

Created: 2024-02-25 06:34

/src/kamailio/src/core/io_wait.h
Line
Count
Source (jump to first uncovered line)
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 than 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
 */
37
38
#ifndef _io_wait_h
39
#define _io_wait_h
40
41
#include <errno.h>
42
#include <string.h>
43
#ifdef HAVE_SIGIO_RT
44
#define __USE_GNU   /* or else F_SETSIG won't be included */
45
#include <sys/types.h>  /* recv */
46
#include <sys/socket.h> /* recv */
47
#include <signal.h>   /* sigprocmask, sigwait a.s.o */
48
#endif
49
50
#ifndef _GNU_SOURCE
51
#define _GNU_SOURCE /* for POLLRDHUP on linux */
52
#endif
53
#include <poll.h>
54
#include <fcntl.h>
55
56
#ifdef HAVE_EPOLL
57
#include <sys/epoll.h>
58
#endif
59
#ifdef HAVE_KQUEUE
60
#include <sys/types.h> /* needed on freebsd */
61
#include <sys/event.h>
62
#include <sys/time.h>
63
#endif
64
#ifdef HAVE_DEVPOLL
65
#include <sys/devpoll.h>
66
#endif
67
#ifdef HAVE_SELECT
68
/* needed on openbsd for select*/
69
#include <sys/time.h>
70
#include <sys/types.h>
71
#include <unistd.h>
72
/* needed according to POSIX for select*/
73
#include <sys/select.h>
74
#endif
75
76
#include "dprint.h"
77
78
#include "poll_types.h" /* poll_types*/
79
#ifdef HAVE_SIGIO_RT
80
#include "pt.h" /* mypid() */
81
#endif
82
83
#include "compiler_opt.h"
84
85
86
#ifdef HAVE_EPOLL
87
/* fix defines for EPOLL */
88
#if defined POLLRDHUP && !defined EPOLLRDHUP
89
#define EPOLLRDHUP POLLRDHUP /* should work on all linuxes */
90
#endif             /* POLLRDHUP && EPOLLRDHUP */
91
#endif             /* HAVE_EPOLL */
92
93
94
extern int _os_ver; /* os version number, needed to select bugs workarounds */
95
96
97
#if 0
98
enum fd_types; /* this should be defined from the including file,
99
          see tcp_main.c for an example,
100
          0 has a special meaning: not used/empty*/
101
#endif
102
103
#ifndef FD_TYPE_DEFINED
104
typedef int fd_type;
105
#define FD_TYPE_DEFINED
106
#endif
107
108
#ifdef __SUNPRO_C
109
#pragma weak handle_io
110
#endif
111
112
/* maps a fd to some other structure; used in almost all cases
113
 * except epoll and maybe kqueue or /dev/poll */
114
typedef struct fd_map
115
{
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
} fd_map_t;
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
typedef struct io_wait_handler
139
{
140
  enum poll_types poll_method;
141
  int flags;
142
  struct fd_map *fd_hash;
143
  int fd_no;     /*  current index used in fd_array and the passed size for
144
           ep_array (for kq_array at least
145
            max(twice the size, kq_changes_size) should be
146
           be passed). */
147
  int max_fd_no; /* maximum fd no, is also the size of fd_array,
148
                   fd_hash  and ep_array*/
149
  /* common stuff for POLL, SIGIO_RT and SELECT
150
   * since poll support is always compiled => this will always be compiled */
151
  struct pollfd *fd_array; /* used also by devpoll as devpoll array */
152
  int crt_fd_array_idx;  /*  crt idx for which handle_io is called
153
               (updated also by del -> internal optimization) */
154
               /* end of common stuff */
155
#ifdef HAVE_EPOLL
156
  int epfd; /* epoll ctrl fd */
157
  struct epoll_event *ep_array;
158
#endif
159
#ifdef HAVE_SIGIO_RT
160
  sigset_t sset; /* signal mask for sigio & sigrtmin */
161
  int signo;     /* real time signal used */
162
#endif
163
#ifdef HAVE_KQUEUE
164
  int kq_fd;
165
  struct kevent *kq_array;   /* used for the eventlist*/
166
  struct kevent *kq_changes; /* used for the changelist */
167
  size_t kq_nchanges;
168
  size_t kq_array_size; /* array size */
169
  size_t kq_changes_size; /* size of the changes array */
170
#endif
171
#ifdef HAVE_DEVPOLL
172
  int dpoll_fd;
173
#endif
174
#ifdef HAVE_SELECT
175
  fd_set main_rset;  /* read set */
176
  fd_set main_wset;  /* write set */
177
  int max_fd_select; /* maximum select used fd */
178
#endif
179
} io_wait_h;
180
181
182
/* get the corresponding fd_map structure pointer */
183
0
#define get_fd_map(h, fd) (&(h)->fd_hash[(fd)])
184
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
0
  do {                             \
189
0
    (pfm)->type = 0 /*F_NONE */; \
190
0
    (pfm)->fd = -1;              \
191
0
  } while(0)
192
193
/* add a fd_map structure to the fd hash */
194
static inline struct fd_map *hash_fd_map(
195
    io_wait_h *h, int fd, short events, fd_type type, void *data)
196
0
{
197
0
  h->fd_hash[fd].fd = fd;
198
0
  h->fd_hash[fd].events = events;
199
0
  h->fd_hash[fd].type = type;
200
0
  h->fd_hash[fd].data = data;
201
0
  return &h->fd_hash[fd];
202
0
}
Unexecuted instantiation: tcp_main.c:hash_fd_map
Unexecuted instantiation: tcp_read.c:hash_fd_map
Unexecuted instantiation: io_wait.c:hash_fd_map
203
204
205
#ifdef HANDLE_IO_INLINE
206
/* generic handle io routine, this must be defined in the including file
207
 * (faster than registering a callback pointer)
208
 *
209
 * params:  fm     - pointer to a fd hash entry
210
 *          events - combinations of POLLIN, POLLOUT, POLLERR & POLLHUP
211
 *          idx    - index in the fd_array (or -1 if not known)
212
 * return: -1 on error
213
 *          0 on EAGAIN or when by some other way it is known that no more
214
 *            io events are queued on the fd (the receive buffer is empty).
215
 *            Useful to detect when there are no more io events queued for
216
 *            sigio_rt, epoll_et, kqueue.
217
 *         >0 on successfull read from the fd (when there might be more io
218
 *            queued -- the receive buffer might still be non-empty)
219
 */
220
inline static int handle_io(struct fd_map *fm, short events, int idx);
221
#else
222
int handle_io(struct fd_map *fm, short events, int idx);
223
#endif
224
225
226
#ifdef HAVE_KQUEUE
227
/*
228
 * kqueue specific function: register a change
229
 * (adds a change to the kevent change array, and if full flushes it first)
230
 *
231
 * TODO: check if the event already exists in the change list or if it's
232
 *       complementary to an event in the list (e.g. EVFILT_WRITE, EV_DELETE
233
 *       and EVFILT_WRITE, EV_ADD for the same fd).
234
 * returns: -1 on error, 0 on success
235
 */
236
static inline int kq_ev_change(
237
    io_wait_h *h, int fd, int filter, int flag, void *data)
238
{
239
  int n;
240
  int r;
241
  struct timespec tspec;
242
243
  if(h->kq_nchanges >= h->kq_changes_size) {
244
    /* changes array full ! */
245
    LM_WARN("kqueue changes array full trying to flush...\n");
246
    tspec.tv_sec = 0;
247
    tspec.tv_nsec = 0;
248
  again:
249
    n = kevent(h->kq_fd, h->kq_changes, h->kq_nchanges, 0, 0, &tspec);
250
    if(unlikely(n == -1)) {
251
      if(unlikely(errno == EINTR))
252
        goto again;
253
      else {
254
        /* for a detailed explanation of what follows see
255
           io_wait_loop_kqueue EV_ERROR case */
256
        if(unlikely(!(errno == EBADF || errno == ENOENT)))
257
          BUG("kq_ev_change: kevent flush changes failed"
258
            " (unexpected error): %s [%d]\n",
259
              strerror(errno), errno);
260
        /* ignore error even if it's not an EBADF/ENOENT */
261
        /* one of the file descriptors is bad, probably already
262
           closed => try to apply changes one-by-one */
263
        for(r = 0; r < h->kq_nchanges; r++) {
264
        retry2:
265
          n = kevent(h->kq_fd, &h->kq_changes[r], 1, 0, 0, &tspec);
266
          if(n == -1) {
267
            if(unlikely(errno == EINTR))
268
              goto retry2;
269
            /* for a detailed explanation of what follows see
270
            io_wait_loop_kqueue EV_ERROR case */
271
            if(unlikely(!(errno == EBADF || errno == ENOENT)))
272
              BUG("kq_ev_change: kevent flush changes failed:"
273
                " (unexpected error) %s [%d] (%d/%lu)\n",
274
                  strerror(errno), errno, r,
275
                  (unsigned long)h->kq_nchanges);
276
            continue; /* skip over it */
277
          }
278
        }
279
      }
280
    }
281
    h->kq_nchanges = 0; /* changes array is empty */
282
  }
283
  EV_SET(&h->kq_changes[h->kq_nchanges], fd, filter, flag, 0, 0,
284
      KEV_UDATA_CAST data);
285
  h->kq_nchanges++;
286
  return 0;
287
}
288
#endif
289
290
291
/* generic io_watch_add function
292
 * Params:
293
 *     h      - pointer to initialized io_wait handle
294
 *     fd     - fd to watch
295
 *     events - bitmap with the fd events for which the fd should be watched
296
 *              (combination of POLLIN and POLLOUT)
297
 *     type   - fd type (non 0 value, returned in the call to handle_io)
298
 *     data   - pointer/private data returned in the handle_io call
299
 * returns 0 on success, -1 on error
300
 *
301
 * WARNING: handle_io() can be called immediately (from io_watch_add()) so
302
 *  make sure that any dependent init. (e.g. data stuff) is made before
303
 *  calling io_watch_add
304
 *
305
 * this version should be faster than pointers to poll_method specific
306
 * functions (it avoids functions calls, the overhead being only an extra
307
 *  switch())*/
308
inline static int io_watch_add(
309
    io_wait_h *h, int fd, short events, fd_type type, void *data)
310
0
{
311
312
  /* helper macros */
313
0
#define fd_array_setup(ev)                                            \
314
0
  do {                                                              \
315
0
    h->fd_array[h->fd_no].fd = fd;                                \
316
0
    h->fd_array[h->fd_no].events = (ev); /* useless for select */ \
317
0
    h->fd_array[h->fd_no].revents = 0;   /* useless for select */ \
318
0
  } while(0)
319
320
0
#define set_fd_flags(f)                                                       \
321
0
  do {                                                                      \
322
0
    flags = fcntl(fd, F_GETFL);                                           \
323
0
    if(flags == -1) {                                                     \
324
0
      LM_ERR("fnctl: GETFL failed: %s [%d]\n", strerror(errno), errno); \
325
0
      goto error;                                                       \
326
0
    }                                                                     \
327
0
    if(fcntl(fd, F_SETFL, flags | (f)) == -1) {                           \
328
0
      LM_ERR("fnctl: SETFL failed: %s [%d]\n", strerror(errno), errno); \
329
0
      goto error;                                                       \
330
0
    }                                                                     \
331
0
  } while(0)
332
333
0
  struct fd_map *e;
334
0
  int flags;
335
0
#ifdef HAVE_EPOLL
336
0
  struct epoll_event ep_event;
337
0
#endif
338
#ifdef HAVE_DEVPOLL
339
  struct pollfd pfd;
340
#endif
341
0
#if defined(HAVE_SIGIO_RT) || defined(HAVE_EPOLL)
342
0
  int n;
343
0
#endif
344
0
#if defined(HAVE_SIGIO_RT)
345
0
  int idx;
346
0
  int check_io;
347
0
  struct pollfd pf;
348
349
0
  check_io = 0; /* set to 1 if we need to check for pre-existing queued
350
           io/data on the fd */
351
0
  idx = -1;
352
0
#endif
353
0
  e = 0;
354
  /* sanity checks */
355
0
  if(unlikely(fd == -1)) {
356
0
    LM_CRIT("fd is -1!\n");
357
0
    goto error;
358
0
  }
359
0
  if(unlikely((events & (POLLIN | POLLOUT)) == 0)) {
360
0
    LM_CRIT("invalid events: 0x%0x\n", events);
361
0
    goto error;
362
0
  }
363
  /* check if not too big */
364
0
  if(unlikely(h->fd_no >= h->max_fd_no)) {
365
0
    LM_CRIT("maximum fd number exceeded: %d/%d\n", h->fd_no, h->max_fd_no);
366
0
    goto error;
367
0
  }
368
0
  DBG("processing io_watch_add(%p, %d, %d, %p) - fd_no=%d\n", h, fd, type,
369
0
      data, h->fd_no);
370
  /*  hash sanity check */
371
0
  e = get_fd_map(h, fd);
372
0
  if(unlikely(e && (e->type != 0 /*F_NONE*/))) {
373
0
    LM_ERR("trying to overwrite entry %d watched for %x"
374
0
         " in the hash %p (fd:%d, type:%d, data:%p) with (%d, %d, %p)\n",
375
0
        fd, events, h, e->fd, e->type, e->data, fd, type, data);
376
0
    e = 0;
377
0
    goto error;
378
0
  }
379
380
0
  if(unlikely((e = hash_fd_map(h, fd, events, type, data)) == 0)) {
381
0
    LM_ERR("failed to hash the fd %d\n", fd);
382
0
    goto error;
383
0
  }
384
0
  switch(h->poll_method) { /* faster than pointer to functions */
385
0
    case POLL_POLL:
386
0
#ifdef POLLRDHUP
387
      /* listen to POLLRDHUP by default (if POLLIN) */
388
0
      events |= ((int)!(events & POLLIN) - 1) & POLLRDHUP;
389
0
#endif /* POLLRDHUP */
390
0
      fd_array_setup(events);
391
0
      set_fd_flags(O_NONBLOCK);
392
0
      break;
393
0
#ifdef HAVE_SELECT
394
0
    case POLL_SELECT:
395
0
      fd_array_setup(events);
396
0
      if(likely(events & POLLIN))
397
0
        FD_SET(fd, &h->main_rset);
398
0
      if(unlikely(events & POLLOUT))
399
0
        FD_SET(fd, &h->main_wset);
400
0
      if(h->max_fd_select < fd)
401
0
        h->max_fd_select = fd;
402
0
      break;
403
0
#endif
404
0
#ifdef HAVE_SIGIO_RT
405
0
    case POLL_SIGIO_RT:
406
0
      fd_array_setup(events);
407
      /* re-set O_ASYNC might be needed, if not done from
408
       * io_watch_del (or if somebody wants to add a fd which has
409
       * already O_ASYNC/F_SETSIG set on a duplicate)
410
       */
411
      /* set async & signal */
412
0
      if(fcntl(fd, F_SETOWN, my_pid()) == -1) {
413
0
        LM_ERR("fnctl: SETOWN on fd %d failed: %s [%d]\n", fd,
414
0
            strerror(errno), errno);
415
0
        goto error;
416
0
      }
417
0
      if(fcntl(fd, F_SETSIG, h->signo) == -1) {
418
0
        LM_ERR("fnctl: SETSIG on fd %d failed: %s [%d]\n", fd,
419
0
            strerror(errno), errno);
420
0
        goto error;
421
0
      }
422
      /* set both non-blocking and async */
423
0
      set_fd_flags(O_ASYNC | O_NONBLOCK);
424
#ifdef EXTRA_DEBUG
425
      DBG("io_watch_add: sigio_rt on f %d, signal %d to pid %d\n", fd,
426
          h->signo, my_pid());
427
#endif
428
      /* empty socket receive buffer, if buffer is already full
429
       * no more space to put packets
430
       * => no more signals are ever generated
431
       * also when moving fds, the freshly moved fd might have
432
       *  already some bytes queued, we want to get them now
433
       *  and not later -- andrei */
434
0
      idx = h->fd_no;
435
0
      check_io = 1;
436
0
      break;
437
0
#endif
438
0
#ifdef HAVE_EPOLL
439
0
    case POLL_EPOLL_LT:
440
0
      ep_event.events =
441
0
#ifdef POLLRDHUP
442
          /* listen for EPOLLRDHUP too */
443
0
          ((EPOLLIN | EPOLLRDHUP) & ((int)!(events & POLLIN) - 1)) |
444
#else  /* POLLRDHUP */
445
          (EPOLLIN & ((int)!(events & POLLIN) - 1)) |
446
#endif /* POLLRDHUP */
447
0
          (EPOLLOUT & ((int)!(events & POLLOUT) - 1));
448
0
      ep_event.data.ptr = e;
449
0
    again1:
450
0
      n = epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
451
0
      if(unlikely(n == -1)) {
452
0
        if(errno == EAGAIN)
453
0
          goto again1;
454
0
        LM_ERR("epoll_ctl on fd %d failed: %s [%d]\n", fd,
455
0
            strerror(errno), errno);
456
0
        goto error;
457
0
      }
458
0
      break;
459
0
    case POLL_EPOLL_ET:
460
0
      set_fd_flags(O_NONBLOCK);
461
0
      ep_event.events =
462
0
#ifdef POLLRDHUP
463
          /* listen for EPOLLRDHUP too */
464
0
          ((EPOLLIN | EPOLLRDHUP) & ((int)!(events & POLLIN) - 1)) |
465
#else  /* POLLRDHUP */
466
          (EPOLLIN & ((int)!(events & POLLIN) - 1)) |
467
#endif /* POLLRDHUP */
468
0
          (EPOLLOUT & ((int)!(events & POLLOUT) - 1)) | EPOLLET;
469
0
      ep_event.data.ptr = e;
470
0
    again2:
471
0
      n = epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
472
0
      if(unlikely(n == -1)) {
473
0
        if(errno == EAGAIN)
474
0
          goto again2;
475
0
        LM_ERR("epoll_ctl on fd %d failed: %s [%d]\n", fd,
476
0
            strerror(errno), errno);
477
0
        goto error;
478
0
      }
479
0
      break;
480
0
#endif
481
#ifdef HAVE_KQUEUE
482
    case POLL_KQUEUE:
483
      if(likely(events & POLLIN)) {
484
        if(unlikely(kq_ev_change(h, fd, EVFILT_READ, EV_ADD, e) == -1))
485
          goto error;
486
      }
487
      if(unlikely(events & POLLOUT)) {
488
        if(unlikely(kq_ev_change(h, fd, EVFILT_WRITE, EV_ADD, e)
489
              == -1)) {
490
          if(likely(events & POLLIN)) {
491
            kq_ev_change(h, fd, EVFILT_READ, EV_DELETE, 0);
492
          }
493
          goto error;
494
        }
495
      }
496
      break;
497
#endif
498
#ifdef HAVE_DEVPOLL
499
    case POLL_DEVPOLL:
500
      pfd.fd = fd;
501
      pfd.events = events;
502
      pfd.revents = 0;
503
    again_devpoll:
504
      if(write(h->dpoll_fd, &pfd, sizeof(pfd)) == -1) {
505
        if(errno == EAGAIN)
506
          goto again_devpoll;
507
        LM_ERR("/dev/poll write of fd %d failed: %s [%d]\n", fd,
508
            strerror(errno), errno);
509
        goto error;
510
      }
511
      break;
512
#endif
513
514
0
    default:
515
0
      LM_CRIT("no support for poll method  %s (%d)\n",
516
0
          poll_method_str[h->poll_method], h->poll_method);
517
0
      goto error;
518
0
  }
519
520
0
  h->fd_no++; /* "activate" changes, for epoll/kqueue/devpoll it
521
           has only informative value */
522
0
#if defined(HAVE_SIGIO_RT)
523
0
  if(check_io) {
524
    /* handle possible pre-existing events */
525
0
    pf.fd = fd;
526
0
    pf.events = events;
527
0
  check_io_again:
528
0
    n = 0;
529
0
    while(e->type && ((n = poll(&pf, 1, 0)) > 0)
530
0
        && (handle_io(e, pf.revents, idx) > 0)
531
0
        && (pf.revents & (e->events | POLLERR | POLLHUP)))
532
0
      ;
533
0
    if(unlikely(e->type && (n == -1))) {
534
0
      if(errno == EINTR)
535
0
        goto check_io_again;
536
0
      LM_ERR("check_io poll on fd %d failed: %s [%d]\n", fd,
537
0
          strerror(errno), errno);
538
0
    }
539
0
  }
540
0
#endif
541
0
  return 0;
542
0
error:
543
0
  if(e)
544
0
    unhash_fd_map(e);
545
0
  return -1;
546
0
#undef fd_array_setup
547
0
#undef set_fd_flags
548
0
}
Unexecuted instantiation: tcp_main.c:io_watch_add
Unexecuted instantiation: tcp_read.c:io_watch_add
Unexecuted instantiation: io_wait.c:io_watch_add
549
550
551
0
#define IO_FD_CLOSING 16
552
/* parameters:    h - handler
553
 *               fd - file descriptor
554
 *            index - index in the fd_array if known, -1 if not
555
 *                    (if index==-1 fd_array will be searched for the
556
 *                     corresponding fd* entry -- slower but unavoidable in
557
 *                     some cases). index is not used (no fd_array) for epoll,
558
 *                     /dev/poll and kqueue
559
 *            flags - optimization flags, e.g. IO_FD_CLOSING, the fd was
560
 *                    or will shortly be closed, in some cases we can avoid
561
 *                    extra remove operations (e.g.: epoll, kqueue, sigio)
562
 * returns 0 if ok, -1 on error */
563
inline static int io_watch_del(io_wait_h *h, int fd, int idx, int flags)
564
0
{
565
566
0
#define fix_fd_array                                                       \
567
0
  do {                                                                   \
568
0
    if(unlikely(idx == -1)) {                                          \
569
      /* fix idx if -1 and needed */                                 \
570
0
      for(idx = 0; (idx < h->fd_no) && (h->fd_array[idx].fd != fd);  \
571
0
          idx++)                                                 \
572
0
        ;                                                          \
573
0
    }                                                                  \
574
0
    if(likely(idx < h->fd_no)) {                                       \
575
0
      memmove(&h->fd_array[idx], &h->fd_array[idx + 1],              \
576
0
          (h->fd_no - (idx + 1)) * sizeof(*(h->fd_array)));      \
577
0
      if((idx <= h->crt_fd_array_idx) && (h->crt_fd_array_idx >= 0)) \
578
0
        h->crt_fd_array_idx--;                                     \
579
0
    }                                                                  \
580
0
  } while(0)
581
582
0
  struct fd_map *e;
583
0
  int events;
584
0
#ifdef HAVE_EPOLL
585
0
  int n;
586
0
  struct epoll_event ep_event;
587
0
#endif
588
#ifdef HAVE_DEVPOLL
589
  struct pollfd pfd;
590
#endif
591
0
#ifdef HAVE_SIGIO_RT
592
0
  int fd_flags;
593
0
#endif
594
595
0
  if(unlikely((fd < 0) || (fd >= h->max_fd_no))) {
596
0
    LM_CRIT("invalid fd %d, not in [0, %d) \n", fd, h->fd_no);
597
0
    goto error;
598
0
  }
599
0
  DBG("DBG: io_watch_del (%p, %d, %d, 0x%x) fd_no=%d called\n", h, fd, idx,
600
0
      flags, h->fd_no);
601
0
  e = get_fd_map(h, fd);
602
  /* more sanity checks */
603
0
  if(unlikely(e == 0)) {
604
0
    LM_CRIT("no corresponding hash entry for %d\n", fd);
605
0
    goto error;
606
0
  }
607
0
  if(unlikely(e->type == 0 /*F_NONE*/)) {
608
0
    LM_ERR("trying to delete already erased"
609
0
         " entry %d in the hash(%d, %d, %p) flags %x)\n",
610
0
        fd, e->fd, e->type, e->data, flags);
611
0
    goto error;
612
0
  }
613
0
  events = e->events;
614
615
0
  switch(h->poll_method) {
616
0
    case POLL_POLL:
617
0
      fix_fd_array;
618
0
      break;
619
0
#ifdef HAVE_SELECT
620
0
    case POLL_SELECT:
621
0
      if(likely(events & POLLIN))
622
0
        FD_CLR(fd, &h->main_rset);
623
0
      if(unlikely(events & POLLOUT))
624
0
        FD_CLR(fd, &h->main_wset);
625
0
      if(unlikely(h->max_fd_select && (h->max_fd_select == fd)))
626
        /* we don't know the prev. max, so we just decrement it */
627
0
        h->max_fd_select--;
628
0
      fix_fd_array;
629
0
      break;
630
0
#endif
631
0
#ifdef HAVE_SIGIO_RT
632
0
    case POLL_SIGIO_RT:
633
      /* the O_ASYNC flag must be reset all the time, the fd
634
       *  can be changed only if  O_ASYNC is reset (if not and
635
       *  the fd is a duplicate, you will get signals from the dup. fd
636
       *  and not from the original, even if the dup. fd was closed
637
       *  and the signals re-set on the original) -- andrei
638
       */
639
      /*if (!(flags & IO_FD_CLOSING)){*/
640
      /* reset ASYNC */
641
0
      fd_flags = fcntl(fd, F_GETFL);
642
0
      if(unlikely(fd_flags == -1)) {
643
0
        LM_ERR("fnctl: GETFL on fd %d failed: %s [%d]\n", fd,
644
0
            strerror(errno), errno);
645
0
        goto error;
646
0
      }
647
0
      if(unlikely(fcntl(fd, F_SETFL, fd_flags & (~O_ASYNC)) == -1)) {
648
0
        LM_ERR("fnctl: SETFL on fd %d failed: %s [%d]\n", fd,
649
0
            strerror(errno), errno);
650
0
        goto error;
651
0
      }
652
0
      fix_fd_array; /* only on success */
653
0
      break;
654
0
#endif
655
0
#ifdef HAVE_EPOLL
656
0
    case POLL_EPOLL_LT:
657
0
    case POLL_EPOLL_ET:
658
      /* epoll doesn't seem to automatically remove sockets,
659
       * if the socket is a duplicate/moved and the original
660
       * is still open. The fd is removed from the epoll set
661
       * only when the original (and all the  copies?) is/are
662
       * closed. This is probably a bug in epoll. --andrei */
663
#ifdef EPOLL_NO_CLOSE_BUG
664
      if(!(flags & IO_FD_CLOSING)) {
665
#endif
666
0
      again_epoll:
667
0
        n = epoll_ctl(h->epfd, EPOLL_CTL_DEL, fd, &ep_event);
668
0
        if(unlikely(n == -1)) {
669
0
          if(errno == EAGAIN)
670
0
            goto again_epoll;
671
0
          LM_ERR("removing fd %d from epoll list failed: %s [%d]\n",
672
0
              fd, strerror(errno), errno);
673
0
          if(unlikely(errno == EBADF)) {
674
0
            LM_ERR("unhashing of invalid fd - %d (epfd %d)\n", fd,
675
0
                h->epfd);
676
0
            unhash_fd_map(e);
677
0
            h->fd_no--;
678
0
          }
679
680
0
          goto error;
681
0
        }
682
#ifdef EPOLL_NO_CLOSE_BUG
683
      }
684
#endif
685
0
      break;
686
0
#endif
687
#ifdef HAVE_KQUEUE
688
    case POLL_KQUEUE:
689
      if(!(flags & IO_FD_CLOSING)) {
690
        if(likely(events & POLLIN)) {
691
          if(unlikely(kq_ev_change(h, fd, EVFILT_READ, EV_DELETE, 0)
692
                == -1)) {
693
            /* try to delete the write filter anyway */
694
            if(events & POLLOUT) {
695
              kq_ev_change(h, fd, EVFILT_WRITE, EV_DELETE, 0);
696
            }
697
            goto error;
698
          }
699
        }
700
        if(unlikely(events & POLLOUT)) {
701
          if(unlikely(kq_ev_change(h, fd, EVFILT_WRITE, EV_DELETE, 0)
702
                == -1))
703
            goto error;
704
        }
705
      }
706
      break;
707
#endif
708
#ifdef HAVE_DEVPOLL
709
    case POLL_DEVPOLL:
710
      /* for /dev/poll the closed fds _must_ be removed
711
           (they are not removed automatically on close()) */
712
      pfd.fd = fd;
713
      pfd.events = POLLREMOVE;
714
      pfd.revents = 0;
715
    again_devpoll:
716
      if(write(h->dpoll_fd, &pfd, sizeof(pfd)) == -1) {
717
        if(errno == EINTR)
718
          goto again_devpoll;
719
        LM_ERR("removing fd %d from /dev/poll failed: %s [%d]\n", fd,
720
            strerror(errno), errno);
721
        goto error;
722
      }
723
      break;
724
#endif
725
0
    default:
726
0
      LM_CRIT("no support for poll method  %s (%d)\n",
727
0
          poll_method_str[h->poll_method], h->poll_method);
728
0
      goto error;
729
0
  }
730
0
  unhash_fd_map(e); /* only on success */
731
0
  h->fd_no--;
732
0
  return 0;
733
0
error:
734
0
  return -1;
735
0
#undef fix_fd_array
736
0
}
Unexecuted instantiation: tcp_main.c:io_watch_del
Unexecuted instantiation: tcp_read.c:io_watch_del
Unexecuted instantiation: io_wait.c:io_watch_del
737
738
739
/* parameters:    h - handler
740
 *               fd - file descriptor
741
 *           events - new events to watch for
742
 *              idx - index in the fd_array if known, -1 if not
743
 *                    (if index==-1 fd_array will be searched for the
744
 *                     corresponding fd* entry -- slower but unavoidable in
745
 *                     some cases). index is not used (no fd_array) for epoll,
746
 *                     /dev/poll and kqueue
747
 * returns 0 if ok, -1 on error */
748
inline static int io_watch_chg(io_wait_h *h, int fd, short events, int idx)
749
0
{
750
751
0
#define fd_array_chg(ev)                                                  \
752
0
  do {                                                                  \
753
0
    if(unlikely(idx == -1)) {                                         \
754
      /* fix idx if -1 and needed */                                \
755
0
      for(idx = 0; (idx < h->fd_no) && (h->fd_array[idx].fd != fd); \
756
0
          idx++)                                                \
757
0
        ;                                                         \
758
0
    }                                                                 \
759
0
    if(likely(idx < h->fd_no)) {                                      \
760
0
      h->fd_array[idx].events = (ev);                               \
761
0
    }                                                                 \
762
0
  } while(0)
763
764
0
  struct fd_map *e;
765
0
  int add_events;
766
0
  int del_events;
767
#ifdef HAVE_DEVPOLL
768
  struct pollfd pfd;
769
#endif
770
0
#ifdef HAVE_EPOLL
771
0
  int n;
772
0
  struct epoll_event ep_event;
773
0
#endif
774
775
0
  if(unlikely((fd < 0) || (fd >= h->max_fd_no))) {
776
0
    LM_CRIT("invalid fd %d, not in [0, %d) \n", fd, h->fd_no);
777
0
    goto error;
778
0
  }
779
0
  if(unlikely((events & (POLLIN | POLLOUT)) == 0)) {
780
0
    LM_CRIT("invalid events: 0x%0x\n", events);
781
0
    goto error;
782
0
  }
783
0
  DBG("DBG: io_watch_chg (%p, %d, 0x%x, 0x%x) fd_no=%d called\n", h, fd,
784
0
      events, idx, h->fd_no);
785
0
  e = get_fd_map(h, fd);
786
  /* more sanity checks */
787
0
  if(unlikely(e == 0)) {
788
0
    LM_CRIT("no corresponding hash entry for %d\n", fd);
789
0
    goto error;
790
0
  }
791
0
  if(unlikely(e->type == 0 /*F_NONE*/)) {
792
0
    LM_ERR("trying to change an already erased"
793
0
         " entry %d in the hash(%d, %d, %p) )\n",
794
0
        fd, e->fd, e->type, e->data);
795
0
    goto error;
796
0
  }
797
798
0
  add_events = events & ~e->events;
799
0
  del_events = e->events & ~events;
800
0
  switch(h->poll_method) {
801
0
    case POLL_POLL:
802
0
#ifdef POLLRDHUP
803
0
      fd_array_chg(events |
804
             /* listen to POLLRDHUP by default (if POLLIN) */
805
0
             (((int)!(events & POLLIN) - 1) & POLLRDHUP));
806
#else  /* POLLRDHUP */
807
      fd_array_chg(events);
808
#endif /* POLLRDHUP */
809
0
      break;
810
0
#ifdef HAVE_SELECT
811
0
    case POLL_SELECT:
812
0
      fd_array_chg(events);
813
0
      if(unlikely(del_events & POLLIN))
814
0
        FD_CLR(fd, &h->main_rset);
815
0
      else if(unlikely(add_events & POLLIN))
816
0
        FD_SET(fd, &h->main_rset);
817
0
      if(likely(del_events & POLLOUT))
818
0
        FD_CLR(fd, &h->main_wset);
819
0
      else if(likely(add_events & POLLOUT))
820
0
        FD_SET(fd, &h->main_wset);
821
0
      break;
822
0
#endif
823
0
#ifdef HAVE_SIGIO_RT
824
0
    case POLL_SIGIO_RT:
825
0
      fd_array_chg(events);
826
      /* no need for check_io, since SIGIO_RT listens by default for all
827
       * the events */
828
0
      break;
829
0
#endif
830
0
#ifdef HAVE_EPOLL
831
0
    case POLL_EPOLL_LT:
832
0
      ep_event.events =
833
0
#ifdef POLLRDHUP
834
          /* listen for EPOLLRDHUP too */
835
0
          ((EPOLLIN | EPOLLRDHUP) & ((int)!(events & POLLIN) - 1)) |
836
#else  /* POLLRDHUP */
837
          (EPOLLIN & ((int)!(events & POLLIN) - 1)) |
838
#endif /* POLLRDHUP */
839
0
          (EPOLLOUT & ((int)!(events & POLLOUT) - 1));
840
0
      ep_event.data.ptr = e;
841
0
    again_epoll_lt:
842
0
      n = epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
843
0
      if(unlikely(n == -1)) {
844
0
        if(errno == EAGAIN)
845
0
          goto again_epoll_lt;
846
0
        LM_ERR("modifying epoll events of fd %d failed: %s [%d]\n", fd,
847
0
            strerror(errno), errno);
848
0
        goto error;
849
0
      }
850
0
      break;
851
0
    case POLL_EPOLL_ET:
852
0
      ep_event.events =
853
0
#ifdef POLLRDHUP
854
          /* listen for EPOLLRDHUP too */
855
0
          ((EPOLLIN | EPOLLRDHUP) & ((int)!(events & POLLIN) - 1)) |
856
#else  /* POLLRDHUP */
857
          (EPOLLIN & ((int)!(events & POLLIN) - 1)) |
858
#endif /* POLLRDHUP */
859
0
          (EPOLLOUT & ((int)!(events & POLLOUT) - 1)) | EPOLLET;
860
0
      ep_event.data.ptr = e;
861
0
    again_epoll_et:
862
0
      n = epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
863
0
      if(unlikely(n == -1)) {
864
0
        if(errno == EAGAIN)
865
0
          goto again_epoll_et;
866
0
        LM_ERR("modifying epoll events of fd %d failed: %s [%d]\n", fd,
867
0
            strerror(errno), errno);
868
0
        goto error;
869
0
      }
870
0
      break;
871
0
#endif
872
#ifdef HAVE_KQUEUE
873
    case POLL_KQUEUE:
874
      if(unlikely(del_events & POLLIN)) {
875
        if(unlikely(kq_ev_change(h, fd, EVFILT_READ, EV_DELETE, 0)
876
              == -1))
877
          goto error;
878
      } else if(unlikely(add_events & POLLIN)) {
879
        if(unlikely(kq_ev_change(h, fd, EVFILT_READ, EV_ADD, e) == -1))
880
          goto error;
881
      }
882
      if(likely(del_events & POLLOUT)) {
883
        if(unlikely(kq_ev_change(h, fd, EVFILT_WRITE, EV_DELETE, 0)
884
              == -1))
885
          goto error;
886
      } else if(likely(add_events & POLLOUT)) {
887
        if(unlikely(kq_ev_change(h, fd, EVFILT_WRITE, EV_ADD, e) == -1))
888
          goto error;
889
      }
890
      break;
891
#endif
892
#ifdef HAVE_DEVPOLL
893
    case POLL_DEVPOLL:
894
      /* for /dev/poll the closed fds _must_ be removed
895
           (they are not removed automatically on close()) */
896
      pfd.fd = fd;
897
      pfd.events = POLLREMOVE;
898
      pfd.revents = 0;
899
    again_devpoll1:
900
      if(unlikely(write(h->dpoll_fd, &pfd, sizeof(pfd)) == -1)) {
901
        if(errno == EINTR)
902
          goto again_devpoll1;
903
        LM_ERR("removing fd %d from /dev/poll failed: %s [%d]\n", fd,
904
            strerror(errno), errno);
905
        goto error;
906
      }
907
    again_devpoll2:
908
      pfd.events = events;
909
      pfd.revents = 0;
910
      if(unlikely(write(h->dpoll_fd, &pfd, sizeof(pfd)) == -1)) {
911
        if(errno == EINTR)
912
          goto again_devpoll2;
913
        LM_ERR("re-adding fd %d to /dev/poll failed: %s [%d]\n", fd,
914
            strerror(errno), errno);
915
        /* error re-adding the fd => mark it as removed/unhash */
916
        unhash_fd_map(e);
917
        goto error;
918
      }
919
      break;
920
#endif
921
0
    default:
922
0
      LM_CRIT("no support for poll method %s (%d)\n",
923
0
          poll_method_str[h->poll_method], h->poll_method);
924
0
      goto error;
925
0
  }
926
0
  e->events = events; /* only on success */
927
0
  return 0;
928
0
error:
929
0
  return -1;
930
0
#undef fix_fd_array
931
0
}
Unexecuted instantiation: tcp_main.c:io_watch_chg
Unexecuted instantiation: tcp_read.c:io_watch_chg
Unexecuted instantiation: io_wait.c:io_watch_chg
932
933
934
/* io_wait_loop_x style function.
935
 * wait for io using poll()
936
 * params: h      - io_wait handle
937
 *         t      - timeout in s
938
 *         repeat - if !=0 handle_io will be called until it returns <=0
939
 * returns: number of IO events handled on success (can be 0), -1 on error
940
 */
941
inline static int io_wait_loop_poll(io_wait_h *h, int t, int repeat)
942
0
{
943
0
  int n, r;
944
0
  int ret;
945
0
  struct fd_map *fm;
946
947
0
again:
948
0
  ret = n = poll(h->fd_array, h->fd_no, t * 1000);
949
0
  if(n == -1) {
950
0
    if(errno == EINTR)
951
0
      goto again; /* signal, ignore it */
952
0
    else {
953
0
      LM_ERR("poll: %s [%d]\n", strerror(errno), errno);
954
0
      goto error;
955
0
    }
956
0
  }
957
0
  for(r = 0; (r < h->fd_no) && n; r++) {
958
0
    fm = get_fd_map(h, h->fd_array[r].fd);
959
0
    if(h->fd_array[r].revents & (fm->events | POLLERR | POLLHUP)) {
960
0
      n--;
961
      /* sanity checks */
962
0
      if(unlikely((h->fd_array[r].fd >= h->max_fd_no)
963
0
            || (h->fd_array[r].fd < 0))) {
964
0
        LM_CRIT("bad fd %d (no in the 0 - %d range)\n",
965
0
            h->fd_array[r].fd, h->max_fd_no);
966
        /* try to continue anyway */
967
0
        h->fd_array[r].events = 0; /* clear the events */
968
0
        continue;
969
0
      }
970
0
      h->crt_fd_array_idx = r;
971
      /* repeat handle_io if repeat, fd still watched (not deleted
972
         *  inside handle_io), handle_io returns that there's still
973
         *  IO and the fd is still watched for the triggering event */
974
0
      while(fm->type && (handle_io(fm, h->fd_array[r].revents, r) > 0)
975
0
          && repeat
976
0
          && ((fm->events | POLLERR | POLLHUP)
977
0
              & h->fd_array[r].revents))
978
0
        ;
979
0
      r = h->crt_fd_array_idx; /* can change due to io_watch_del(fd)
980
                      array shifting */
981
0
    }
982
0
  }
983
0
error:
984
0
  return ret;
985
0
}
Unexecuted instantiation: tcp_main.c:io_wait_loop_poll
Unexecuted instantiation: tcp_read.c:io_wait_loop_poll
Unexecuted instantiation: io_wait.c:io_wait_loop_poll
986
987
988
#ifdef HAVE_SELECT
989
/* wait for io using select */
990
inline static int io_wait_loop_select(io_wait_h *h, int t, int repeat)
991
0
{
992
0
  fd_set sel_rset;
993
0
  fd_set sel_wset;
994
0
  int n, ret;
995
0
  struct timeval timeout;
996
0
  int r;
997
0
  struct fd_map *fm;
998
0
  int revents;
999
1000
0
again:
1001
0
  sel_rset = h->main_rset;
1002
0
  sel_wset = h->main_wset;
1003
0
  timeout.tv_sec = t;
1004
0
  timeout.tv_usec = 0;
1005
0
  ret = n = select(h->max_fd_select + 1, &sel_rset, &sel_wset, 0, &timeout);
1006
0
  if(n < 0) {
1007
0
    if(errno == EINTR)
1008
0
      goto again; /* just a signal */
1009
0
    LM_ERR("select: %s [%d]\n", strerror(errno), errno);
1010
0
    n = 0;
1011
    /* continue */
1012
0
  }
1013
  /* use poll fd array */
1014
0
  for(r = 0; (r < h->fd_no) && n; r++) {
1015
0
    revents = 0;
1016
0
    if(likely(FD_ISSET(h->fd_array[r].fd, &sel_rset)))
1017
0
      revents |= POLLIN;
1018
0
    if(unlikely(FD_ISSET(h->fd_array[r].fd, &sel_wset)))
1019
0
      revents |= POLLOUT;
1020
0
    if(unlikely(revents)) {
1021
0
      h->crt_fd_array_idx = r;
1022
0
      fm = get_fd_map(h, h->fd_array[r].fd);
1023
0
      while(fm->type && (fm->events & revents)
1024
0
          && (handle_io(fm, revents, r) > 0) && repeat)
1025
0
        ;
1026
0
      r = h->crt_fd_array_idx; /* can change due to io_watch_del(fd)
1027
                      array shifting */
1028
0
      n--;
1029
0
    }
1030
0
  };
1031
0
  return ret;
1032
0
}
Unexecuted instantiation: tcp_main.c:io_wait_loop_select
Unexecuted instantiation: tcp_read.c:io_wait_loop_select
Unexecuted instantiation: io_wait.c:io_wait_loop_select
1033
#endif
1034
1035
1036
#ifdef HAVE_EPOLL
1037
inline static int io_wait_loop_epoll(io_wait_h *h, int t, int repeat)
1038
0
{
1039
0
  int n, r;
1040
0
  struct fd_map *fm;
1041
0
  int revents;
1042
1043
0
again:
1044
0
  n = epoll_wait(h->epfd, h->ep_array, h->fd_no, t * 1000);
1045
0
  if(unlikely(n == -1)) {
1046
0
    if(errno == EINTR)
1047
0
      goto again; /* signal, ignore it */
1048
0
    else {
1049
0
      LM_ERR("epoll_wait(%d, %p, %d, %d): %s [%d]\n", h->epfd,
1050
0
          h->ep_array, h->fd_no, t * 1000, strerror(errno), errno);
1051
0
      goto error;
1052
0
    }
1053
0
  }
1054
#if 0
1055
    if (n>1){
1056
      for(r=0; r<n; r++){
1057
        LM_ERR("ep_array[%d]= %x, %p\n",
1058
          r, h->ep_array[r].events, h->ep_array[r].data.ptr);
1059
      }
1060
    }
1061
#endif
1062
0
  for(r = 0; r < n; r++) {
1063
0
    revents =
1064
0
        (POLLIN & (!(h->ep_array[r].events & (EPOLLIN | EPOLLPRI)) - 1))
1065
0
        | (POLLOUT & (!(h->ep_array[r].events & EPOLLOUT) - 1))
1066
0
        | (POLLERR & (!(h->ep_array[r].events & EPOLLERR) - 1))
1067
0
        | (POLLHUP & (!(h->ep_array[r].events & EPOLLHUP) - 1))
1068
0
#ifdef POLLRDHUP
1069
0
        | (POLLRDHUP & (!(h->ep_array[r].events & EPOLLRDHUP) - 1))
1070
0
#endif
1071
0
        ;
1072
0
    if(likely(revents)) {
1073
0
      fm = (struct fd_map *)h->ep_array[r].data.ptr;
1074
0
      while(fm->type && ((fm->events | POLLERR | POLLHUP) & revents)
1075
0
          && (handle_io(fm, revents, -1) > 0) && repeat)
1076
0
        ;
1077
0
    } else {
1078
0
      LM_ERR("unexpected event %x on %d/%d, data=%p\n",
1079
0
          h->ep_array[r].events, r + 1, n, h->ep_array[r].data.ptr);
1080
0
    }
1081
0
  }
1082
0
error:
1083
0
  return n;
1084
0
}
Unexecuted instantiation: tcp_main.c:io_wait_loop_epoll
Unexecuted instantiation: tcp_read.c:io_wait_loop_epoll
Unexecuted instantiation: io_wait.c:io_wait_loop_epoll
1085
#endif
1086
1087
1088
#ifdef HAVE_KQUEUE
1089
inline static int io_wait_loop_kqueue(io_wait_h *h, int t, int repeat)
1090
{
1091
  int n, r;
1092
  struct timespec tspec;
1093
  struct fd_map *fm;
1094
  int orig_changes;
1095
  int apply_changes;
1096
  int revents;
1097
1098
  tspec.tv_sec = t;
1099
  tspec.tv_nsec = 0;
1100
  orig_changes = h->kq_nchanges;
1101
  apply_changes = orig_changes;
1102
  do {
1103
  again:
1104
    n = kevent(h->kq_fd, h->kq_changes, apply_changes, h->kq_array,
1105
        h->kq_array_size, &tspec);
1106
    if(unlikely(n == -1)) {
1107
      if(unlikely(errno == EINTR))
1108
        goto again; /* signal, ignore it */
1109
      else {
1110
        /* for a detailed explanation of what follows see below
1111
           the EV_ERROR case */
1112
        if(unlikely(!(errno == EBADF || errno == ENOENT)))
1113
          BUG("io_wait_loop_kqueue: kevent: unexpected error"
1114
            " %s [%d]\n",
1115
              strerror(errno), errno);
1116
        /* some of the FDs in kq_changes are bad (already closed)
1117
           and there is not enough space in kq_array to return all
1118
           of them back */
1119
        apply_changes = h->kq_array_size;
1120
        goto again;
1121
      }
1122
    }
1123
    /* remove applied changes */
1124
    h->kq_nchanges -= apply_changes;
1125
    if(unlikely(apply_changes < orig_changes)) {
1126
      orig_changes -= apply_changes;
1127
      memmove(&h->kq_changes[0], &h->kq_changes[apply_changes],
1128
          sizeof(h->kq_changes[0]) * h->kq_nchanges);
1129
      apply_changes = (orig_changes < h->kq_array_size)
1130
                  ? orig_changes
1131
                  : h->kq_array_size;
1132
    } else {
1133
      orig_changes = 0;
1134
      apply_changes = 0;
1135
    }
1136
    for(r = 0; r < n; r++) {
1137
#ifdef EXTRA_DEBUG
1138
      DBG("DBG: kqueue: event %d/%d: fd=%d, udata=%lx, flags=0x%x\n", r,
1139
          n, h->kq_array[r].ident, (long)h->kq_array[r].udata,
1140
          h->kq_array[r].flags);
1141
#endif
1142
      if(unlikely((h->kq_array[r].flags & EV_ERROR)
1143
            || h->kq_array[r].udata == 0)) {
1144
        /* error in changes: we ignore it if it has to do with a
1145
           bad fd or update==0. It can be caused by trying to remove an
1146
           already closed fd: race between adding something to the
1147
           changes array, close() and applying the changes (EBADF).
1148
           E.g. for ser tcp: tcp_main sends a fd to child for reading
1149
            => deletes it from the watched fds => the changes array
1150
          will contain an EV_DELETE for it. Before the changes
1151
          are applied (they are at the end of the main io_wait loop,
1152
          after all the fd events were processed), a CON_ERR sent
1153
          to tcp_main by a sender (send fail) is processed and causes
1154
          the fd to be closed. When the changes are applied =>
1155
          error for the EV_DELETE attempt of a closed fd.
1156
          Something similar can happen when a fd is scheduled
1157
          for removal, is close()'ed before being removed and
1158
          re-opened(a new sock. get the same fd). When the
1159
          watched fd changes will be applied the fd will be valid
1160
          (so no EBADF), but it's not already watch => ENOENT.
1161
          We report a BUG for the other errors (there's nothing
1162
          constructive we can do if we get an error we don't know
1163
          how to handle), but apart from that we ignore it in the
1164
          idea that it is better apply the rest of the changes,
1165
          rather than dropping all of them.
1166
        */
1167
        /*
1168
          example EV_ERROR for trying to delete a read watched fd,
1169
          that was already closed:
1170
          {
1171
            ident = 63,  [fd]
1172
            filter = -1, [EVFILT_READ]
1173
            flags = 16384, [EV_ERROR]
1174
            fflags = 0,
1175
            data = 9, [errno = EBADF]
1176
            udata = 0x0
1177
          }
1178
        */
1179
        if(h->kq_array[r].data != EBADF
1180
            && h->kq_array[r].data != ENOENT)
1181
          BUG("io_wait_loop_kqueue: kevent unexpected error on "
1182
            "fd %ld udata %lx: %s [%ld]\n",
1183
              (long)h->kq_array[r].ident,
1184
              (long)h->kq_array[r].udata,
1185
              strerror(h->kq_array[r].data),
1186
              (long)h->kq_array[r].data);
1187
      } else {
1188
        fm = (struct fd_map *)h->kq_array[r].udata;
1189
        if(likely(h->kq_array[r].filter == EVFILT_READ)) {
1190
          revents = POLLIN
1191
                | (((int)!(h->kq_array[r].flags & EV_EOF) - 1)
1192
                    & POLLHUP)
1193
                | (((int)!((h->kq_array[r].flags & EV_EOF)
1194
                      && h->kq_array[r].fflags != 0)
1195
                     - 1)
1196
                    & POLLERR);
1197
          while(fm->type && (fm->events & revents)
1198
              && (handle_io(fm, revents, -1) > 0) && repeat)
1199
            ;
1200
        } else if(h->kq_array[r].filter == EVFILT_WRITE) {
1201
          revents = POLLOUT
1202
                | (((int)!(h->kq_array[r].flags & EV_EOF) - 1)
1203
                    & POLLHUP)
1204
                | (((int)!((h->kq_array[r].flags & EV_EOF)
1205
                      && h->kq_array[r].fflags != 0)
1206
                     - 1)
1207
                    & POLLERR);
1208
          while(fm->type && (fm->events & revents)
1209
              && (handle_io(fm, revents, -1) > 0) && repeat)
1210
            ;
1211
        } else {
1212
          BUG("io_wait_loop_kqueue: unknown filter: kqueue: event "
1213
            "%d/%d: fd=%d, filter=%d, flags=0x%x, fflags=0x%x,"
1214
            " data=%lx, udata=%lx\n",
1215
              r, n, (int)h->kq_array[r].ident,
1216
              (int)h->kq_array[r].filter, h->kq_array[r].flags,
1217
              h->kq_array[r].fflags,
1218
              (unsigned long)h->kq_array[r].data,
1219
              (unsigned long)h->kq_array[r].udata);
1220
        }
1221
      }
1222
    }
1223
  } while(unlikely(orig_changes));
1224
  return n;
1225
}
1226
#endif
1227
1228
1229
#ifdef HAVE_SIGIO_RT
1230
/* sigio rt version has no repeat (it doesn't make sense)*/
1231
inline static int io_wait_loop_sigio_rt(io_wait_h *h, int t)
1232
0
{
1233
0
  int n;
1234
0
  int ret;
1235
0
  struct timespec ts;
1236
0
  siginfo_t siginfo;
1237
0
  int sigio_band;
1238
0
  int sigio_fd;
1239
0
  struct fd_map *fm;
1240
0
  int revents;
1241
0
#ifdef SIGINFO64_WORKAROUND
1242
0
  int *pi;
1243
0
#endif
1244
1245
1246
0
  ret = 1; /* 1 event per call normally */
1247
0
  ts.tv_sec = t;
1248
0
  ts.tv_nsec = 0;
1249
0
  if(unlikely(!sigismember(&h->sset, h->signo)
1250
0
        || !sigismember(&h->sset, SIGIO))) {
1251
0
    LM_CRIT("the signal mask is not properly set!\n");
1252
0
    goto error;
1253
0
  }
1254
0
again:
1255
0
  n = sigtimedwait(&h->sset, &siginfo, &ts);
1256
0
  if(unlikely(n == -1)) {
1257
0
    if(errno == EINTR)
1258
0
      goto again;        /* some other signal, ignore it */
1259
0
    else if(errno == EAGAIN) { /* timeout */
1260
0
      ret = 0;
1261
0
      goto end;
1262
0
    } else {
1263
0
      LM_ERR("sigtimed_wait %s [%d]\n", strerror(errno), errno);
1264
0
      goto error;
1265
0
    }
1266
0
  }
1267
0
  if(likely(n != SIGIO)) {
1268
0
#ifdef SIGINFO64_WORKAROUND
1269
    /* on linux siginfo.si_band is defined as long in userspace
1270
     * and as int in kernel (< 2.6.5) => on 64 bits things will break!
1271
     * (si_band will include si_fd, and si_fd will contain
1272
     *  garbage).
1273
     *  see /usr/src/linux/include/asm-generic/siginfo.h and
1274
     *      /usr/include/bits/siginfo.h
1275
     *  On newer kernels this is fixed (si_band is long in the kernel too).
1276
     * -- andrei */
1277
0
    if((_os_ver < 0x020605) && (sizeof(siginfo.si_band) > sizeof(int))) {
1278
0
      pi = (int *)(void *)&siginfo
1279
0
             .si_band; /* avoid type punning warnings */
1280
0
      sigio_band = *pi;
1281
0
      sigio_fd = *(pi + 1);
1282
0
    } else
1283
0
#endif
1284
0
    {
1285
0
      sigio_band = siginfo.si_band;
1286
0
      sigio_fd = siginfo.si_fd;
1287
0
    }
1288
0
    if(unlikely(siginfo.si_code == SI_SIGIO)) {
1289
      /* old style, we don't know the event (linux 2.2.?) */
1290
0
      LM_WARN("old style sigio interface\n");
1291
0
      fm = get_fd_map(h, sigio_fd);
1292
      /* we can have queued signals generated by fds not watched
1293
       * any more, or by fds in transition, to a child => ignore them*/
1294
0
      if(fm->type)
1295
0
        handle_io(fm, POLLIN | POLLOUT, -1);
1296
0
    } else {
1297
      /* si_code contains the SIGPOLL reason: POLL_IN, POLL_OUT,
1298
       *  POLL_MSG, POLL_ERR, POLL_PRI or POLL_HUP
1299
       * and si_band the translated poll event bitmap:
1300
       *  POLLIN|POLLRDNORM  (=POLL_IN),
1301
       *  POLLOUT|POLLWRNORM|POLLWRBAND (=POLL_OUT),
1302
       *  POLLIN|POLLRDNORM|POLLMSG (=POLL_MSG),
1303
       *  POLLERR (=POLL_ERR),
1304
       *  POLLPRI|POLLRDBAND (=POLL_PRI),
1305
       *  POLLHUP|POLLERR (=POLL_HUP)
1306
       *  [linux 2.6.22 fs/fcntl.c:447]
1307
       */
1308
#ifdef EXTRA_DEBUG
1309
      DBG("io_wait_loop_sigio_rt: siginfo: signal=%d (%d),"
1310
        " si_code=%d, si_band=0x%x,"
1311
        " si_fd=%d\n",
1312
          siginfo.si_signo, n, siginfo.si_code, (unsigned)sigio_band,
1313
          sigio_fd);
1314
#endif
1315
      /* on some errors (e.g. when receiving TCP RST), sigio_band will
1316
       * be set to 0x08 (POLLERR) or 0x18 (POLLERR|POLLHUP - on stream
1317
       *  unix socket close) , so better catch all events --andrei */
1318
0
      if(likely(sigio_band)) {
1319
0
        fm = get_fd_map(h, sigio_fd);
1320
0
        revents = sigio_band;
1321
        /* fix revents==POLLPRI case */
1322
0
        revents |= (!(revents & POLLPRI) - 1) & POLLIN;
1323
        /* we can have queued signals generated by fds not watched
1324
         * any more, or by fds in transition, to a child
1325
         * => ignore them */
1326
0
        if(fm->type && ((fm->events | POLLERR | POLLHUP) & revents))
1327
0
          handle_io(fm, revents, -1);
1328
0
        else
1329
0
          DBG("WARNING: io_wait_loop_sigio_rt: ignoring event"
1330
0
            " %x on fd %d, watching for %x, si_code=%x "
1331
0
            "(fm->type=%d, fm->fd=%d, fm->data=%p)\n",
1332
0
              sigio_band, sigio_fd, fm->events, siginfo.si_code,
1333
0
              fm->type, fm->fd, fm->data);
1334
0
      } else {
1335
0
        LM_ERR("unexpected event on fd %d: %x\n", sigio_fd, sigio_band);
1336
0
      }
1337
0
    }
1338
0
  } else {
1339
    /* signal queue overflow
1340
     * TODO: increase signal queue size: 2.4x /proc/.., 2.6x -rlimits */
1341
0
    LM_WARN("signal queue overflowed - falling back to poll\n");
1342
    /* clear real-time signal queue
1343
     * both SIG_IGN and SIG_DFL are needed , it doesn't work
1344
     * only with SIG_DFL  */
1345
0
    if(signal(h->signo, SIG_IGN) == SIG_ERR) {
1346
0
      LM_CRIT("do_poll: couldn't reset signal to IGN\n");
1347
0
    }
1348
1349
0
    if(signal(h->signo, SIG_DFL) == SIG_ERR) {
1350
0
      LM_CRIT("do_poll: couldn't reset signal to DFL\n");
1351
0
    }
1352
    /* falling back to normal poll */
1353
0
    ret = io_wait_loop_poll(h, -1, 1);
1354
0
  }
1355
0
end:
1356
0
  return ret;
1357
0
error:
1358
0
  return -1;
1359
0
}
Unexecuted instantiation: tcp_main.c:io_wait_loop_sigio_rt
Unexecuted instantiation: tcp_read.c:io_wait_loop_sigio_rt
Unexecuted instantiation: io_wait.c:io_wait_loop_sigio_rt
1360
#endif
1361
1362
1363
#ifdef HAVE_DEVPOLL
1364
inline static int io_wait_loop_devpoll(io_wait_h *h, int t, int repeat)
1365
{
1366
  int n, r;
1367
  int ret;
1368
  struct dvpoll dpoll;
1369
  struct fd_map *fm;
1370
1371
  dpoll.dp_timeout = t * 1000;
1372
  dpoll.dp_nfds = h->fd_no;
1373
  dpoll.dp_fds = h->fd_array;
1374
again:
1375
  ret = n = ioctl(h->dpoll_fd, DP_POLL, &dpoll);
1376
  if(unlikely(n == -1)) {
1377
    if(errno == EINTR)
1378
      goto again; /* signal, ignore it */
1379
    else {
1380
      LM_ERR("ioctl: %s [%d]\n", strerror(errno), errno);
1381
      goto error;
1382
    }
1383
  }
1384
  for(r = 0; r < n; r++) {
1385
    if(h->fd_array[r].revents & (POLLNVAL | POLLERR)) {
1386
      LM_ERR("pollinval returned for fd %d, revents=%x\n",
1387
          h->fd_array[r].fd, h->fd_array[r].revents);
1388
    }
1389
    /* POLLIN|POLLHUP just go through */
1390
    fm = get_fd_map(h, h->fd_array[r].fd);
1391
    while(fm->type && (fm->events & h->fd_array[r].revents)
1392
        && (handle_io(fm, h->fd_array[r].revents, r) > 0) && repeat)
1393
      ;
1394
  }
1395
error:
1396
  return ret;
1397
}
1398
#endif
1399
1400
1401
/* init */
1402
1403
1404
/* initializes the static vars/arrays
1405
 * params:      h - pointer to the io_wait_h that will be initialized
1406
 *         max_fd - maximum allowed fd number
1407
 *         poll_m - poll method (0 for automatic best fit)
1408
 */
1409
int init_io_wait(io_wait_h *h, int max_fd, enum poll_types poll_method);
1410
1411
/* destroys everything init_io_wait allocated */
1412
void destroy_io_wait(io_wait_h *h);
1413
1414
1415
#endif