| 321 | |
| 322 | #ifdef HAVE_KQUEUE |
| 323 | inline static int io_wait_loop_kqueue(io_wait_h* h, int t, int repeat) |
| 324 | { |
| 325 | int ret, n, r; |
| 326 | struct timespec tspec; |
| 327 | struct fd_map *e; |
| 328 | unsigned int curr_time; |
| 329 | |
| 330 | tspec.tv_sec=t; |
| 331 | tspec.tv_nsec=0; |
| 332 | again: |
| 333 | ret=n=kevent(h->kq_fd, h->kq_changes, h->kq_nchanges, h->kq_array, |
| 334 | h->fd_no, &tspec); |
| 335 | if (n==-1){ |
| 336 | if (errno==EINTR) goto again; /* signal, ignore it */ |
| 337 | else{ |
| 338 | LM_ERR("[%s] kevent: %s [%d]\n", h->name, |
| 339 | strerror(errno), errno); |
| 340 | goto error; |
| 341 | } |
| 342 | } |
| 343 | |
| 344 | curr_time = get_ticks(); |
| 345 | |
| 346 | h->kq_nchanges=0; /* reset changes array */ |
| 347 | for (r=0; r<n; r++){ |
| 348 | #ifdef EXTRA_DEBUG |
| 349 | LM_DBG("[%s] event %d/%d: fd=%d, udata=%lx, flags=0x%x\n", |
| 350 | h->name, r, n, h->kq_array[r].ident, |
| 351 | (long)h->kq_array[r].udata, |
| 352 | h->kq_array[r].flags); |
| 353 | #endif |
| 354 | if (h->kq_array[r].flags & EV_ERROR){ |
| 355 | /* error in changes: we ignore it, it can be caused by |
| 356 | trying to remove an already closed fd: race between |
| 357 | adding smething to the changes array, close() and |
| 358 | applying the changes */ |
| 359 | LM_INFO("[%s] kevent error on fd %u: %s [%ld]\n", |
| 360 | h->name, (unsigned int)h->kq_array[r].ident, |
| 361 | strerror(h->kq_array[r].data), |
| 362 | (long)h->kq_array[r].data); |
| 363 | }else /* READ/EOF */ |
| 364 | ((struct fd_map*)h->kq_array[r].udata)->flags |= |
| 365 | IO_WATCH_PRV_TRIG_READ; |
| 366 | } |
| 367 | /* now do the actual running of IO handlers */ |
| 368 | for(r=h->fd_no-1; (r>=0) && n ; r--) { |
| 369 | e = get_fd_map(h, h->fd_array[r].fd); |
| 370 | if ( e->flags & IO_WATCH_PRV_TRIG_READ ) { |
| 371 | e->flags &= ~IO_WATCH_PRV_TRIG_READ; |
| 372 | while((handle_io( e, r, IO_WATCH_READ)>0) && repeat); |
| 373 | n--; |
| 374 | } else if ( e->timeout!=0 && e->timeout<=curr_time ) { |
| 375 | e->timeout = 0; |
| 376 | handle_io( e, r, IO_WATCH_TIMEOUT); |
| 377 | } |
| 378 | } |
| 379 | |
| 380 | error: |