00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #ifndef _io_wait_h
00055 #define _io_wait_h
00056
00057 #include <errno.h>
00058 #include <string.h>
00059 #ifdef HAVE_SIGIO_RT
00060 #define __USE_GNU
00061 #include <sys/types.h>
00062 #include <sys/socket.h>
00063 #include <signal.h>
00064 #endif
00065 #ifdef HAVE_EPOLL
00066 #include <sys/epoll.h>
00067 #endif
00068 #ifdef HAVE_KQUEUE
00069 #include <sys/types.h>
00070 #include <sys/event.h>
00071 #include <sys/time.h>
00072 #endif
00073 #ifdef HAVE_DEVPOLL
00074 #include <sys/devpoll.h>
00075 #endif
00076 #ifdef HAVE_SELECT
00077
00078 #include <sys/time.h>
00079 #include <sys/types.h>
00080 #include <unistd.h>
00081
00082 #include <sys/select.h>
00083 #endif
00084 #include <sys/poll.h>
00085 #include <fcntl.h>
00086
00087 #include "dprint.h"
00088
00089 #include "poll_types.h"
00090 #ifdef HAVE_SIGIO_RT
00091 #include "pt.h"
00092 #endif
00093
00094
00095 #if 0
00096 enum fd_types;
00097
00098
00099 #endif
00100
00101 #ifndef FD_TYPE_DEFINED
00102 typedef int fd_type;
00103 #define FD_TYPE_DEFINED
00104 #endif
00105
00106
00107
00108 struct fd_map{
00109 int fd;
00110 fd_type type;
00111 void* data;
00112 };
00113
00114
00115 #ifdef HAVE_KQUEUE
00116 #ifndef KQ_CHANGES_ARRAY_SIZE
00117 #define KQ_CHANGES_ARRAY_SIZE 128
00118
00119 #ifdef __OS_netbsd
00120 #define KEV_UDATA_CAST (intptr_t)
00121 #else
00122 #define KEV_UDATA_CAST
00123 #endif
00124
00125 #endif
00126 #endif
00127
00128
00129
00130 struct io_wait_handler{
00131 #ifdef HAVE_EPOLL
00132 struct epoll_event* ep_array;
00133 int epfd;
00134 #endif
00135 #ifdef HAVE_SIGIO_RT
00136 sigset_t sset;
00137 int signo;
00138 #endif
00139 #ifdef HAVE_KQUEUE
00140 struct kevent* kq_array;
00141 struct kevent* kq_changes;
00142 size_t kq_nchanges;
00143 size_t kq_changes_size;
00144 int kq_fd;
00145 #endif
00146 #ifdef HAVE_DEVPOLL
00147 int dpoll_fd;
00148 #endif
00149 #ifdef HAVE_SELECT
00150 fd_set master_set;
00151 int max_fd_select;
00152 #endif
00153
00154
00155 struct fd_map* fd_hash;
00156 struct pollfd* fd_array;
00157 int fd_no;
00158 int max_fd_no;
00159
00160 enum poll_types poll_method;
00161 int flags;
00162 };
00163
00164 typedef struct io_wait_handler io_wait_h;
00165
00166
00167
00168 #define get_fd_map(h, fd) (&(h)->fd_hash[(fd)])
00169
00170
00171
00172
00173 #define unhash_fd_map(pfm) \
00174 do{ \
00175 (pfm)->type=0 ; \
00176 (pfm)->fd=-1; \
00177 }while(0)
00178
00179
00180 static inline struct fd_map* hash_fd_map( io_wait_h* h,
00181 int fd,
00182 fd_type type,
00183 void* data)
00184 {
00185 h->fd_hash[fd].fd=fd;
00186 h->fd_hash[fd].type=type;
00187 h->fd_hash[fd].data=data;
00188 return &h->fd_hash[fd];
00189 }
00190
00191
00192
00193 #ifdef HANDLE_IO_INLINE
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 inline static int handle_io(struct fd_map* fm, int idx);
00209 #else
00210 static int handle_io(struct fd_map* fm, int idx) {
00211 return 0;
00212 }
00213 #endif
00214
00215
00216
00217 #ifdef HAVE_KQUEUE
00218
00219
00220
00221
00222
00223 static inline int kq_ev_change(io_wait_h* h, int fd, int filter, int flag,
00224 void* data)
00225 {
00226 int n;
00227 struct timespec tspec;
00228
00229 if (h->kq_nchanges>=h->kq_changes_size){
00230
00231 LM_WARN("kqueue changes array full trying to flush...\n");
00232 tspec.tv_sec=0;
00233 tspec.tv_nsec=0;
00234 again:
00235 n=kevent(h->kq_fd, h->kq_changes, h->kq_nchanges, 0, 0, &tspec);
00236 if (n==-1){
00237 if (errno==EINTR) goto again;
00238 LM_ERR("kevent flush changes failed: %s [%d]\n",
00239 strerror(errno), errno);
00240 return -1;
00241 }
00242 h->kq_nchanges=0;
00243 }
00244 EV_SET(&h->kq_changes[h->kq_nchanges], fd, filter, flag, 0, 0,
00245 KEV_UDATA_CAST data);
00246 h->kq_nchanges++;
00247 return 0;
00248 }
00249 #endif
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 inline static int io_watch_add( io_wait_h* h,
00261 int fd,
00262 fd_type type,
00263 void* data)
00264 {
00265
00266
00267 #define fd_array_setup \
00268 do{ \
00269 h->fd_array[h->fd_no].fd=fd; \
00270 h->fd_array[h->fd_no].events=POLLIN; \
00271 h->fd_array[h->fd_no].revents=0; \
00272 }while(0)
00273
00274 #define set_fd_flags(f) \
00275 do{ \
00276 flags=fcntl(fd, F_GETFL); \
00277 if (flags==-1){ \
00278 LM_ERR("fnctl: GETFL failed:" \
00279 " %s [%d]\n", strerror(errno), errno); \
00280 goto error; \
00281 } \
00282 if (fcntl(fd, F_SETFL, flags|(f))==-1){ \
00283 LM_ERR("fnctl: SETFL" \
00284 " failed: %s [%d]\n", strerror(errno), errno); \
00285 goto error; \
00286 } \
00287 }while(0)
00288
00289
00290 struct fd_map* e;
00291 int flags;
00292 #ifdef HAVE_EPOLL
00293 struct epoll_event ep_event;
00294 #endif
00295 #ifdef HAVE_DEVPOLL
00296 struct pollfd pfd;
00297 #endif
00298 #if defined(HAVE_SIGIO_RT) || defined (HAVE_EPOLL)
00299 int n;
00300 int idx;
00301 int check_io;
00302 struct pollfd pf;
00303
00304 check_io=0;
00305
00306 idx=-1;
00307 #endif
00308 e=0;
00309 if (fd==-1){
00310 LM_CRIT("fd is -1!\n");
00311 goto error;
00312 }
00313
00314 if (h->fd_no>=h->max_fd_no){
00315 LM_CRIT("maximum fd number exceeded:"
00316 " %d/%d\n", h->fd_no, h->max_fd_no);
00317 goto error;
00318 }
00319 LM_DBG("io_watch_add(%p, %d, %d, %p), fd_no=%d\n",
00320 h, fd, type, data, h->fd_no);
00321
00322 e=get_fd_map(h, fd);
00323 if (e && (e->type!=0 )){
00324 LM_ERR("trying to overwrite entry %d"
00325 " in the hash(%d, %d, %p) with (%d, %d, %p)\n",
00326 fd, e->fd, e->type, e->data, fd, type, data);
00327 goto error;
00328 }
00329
00330 if ((e=hash_fd_map(h, fd, type, data))==0){
00331 LM_ERR("failed to hash the fd %d\n", fd);
00332 goto error;
00333 }
00334 switch(h->poll_method){
00335 case POLL_POLL:
00336 fd_array_setup;
00337 set_fd_flags(O_NONBLOCK);
00338 break;
00339 #ifdef HAVE_SELECT
00340 case POLL_SELECT:
00341 fd_array_setup;
00342 FD_SET(fd, &h->master_set);
00343 if (h->max_fd_select<fd) h->max_fd_select=fd;
00344 break;
00345 #endif
00346 #ifdef HAVE_SIGIO_RT
00347 case POLL_SIGIO_RT:
00348 fd_array_setup;
00349
00350
00351
00352
00353
00354 if (fcntl(fd, F_SETOWN, my_pid())==-1){
00355 LM_ERR("fnctl: SETOWN"
00356 " failed: %s [%d]\n", strerror(errno), errno);
00357 goto error;
00358 }
00359 if (fcntl(fd, F_SETSIG, h->signo)==-1){
00360 LM_ERR("fnctl: SETSIG"
00361 " failed: %s [%d]\n", strerror(errno), errno);
00362 goto error;
00363 }
00364
00365 set_fd_flags(O_ASYNC| O_NONBLOCK);
00366 #ifdef EXTRA_DEBUG
00367 LM_DBG("sigio_rt on f %d, signal %d to pid %d\n",
00368 fd, h->signo, my_pid());
00369 #endif
00370
00371
00372
00373
00374
00375
00376 idx=h->fd_no;
00377 check_io=1;
00378 break;
00379 #endif
00380 #ifdef HAVE_EPOLL
00381 case POLL_EPOLL_LT:
00382 ep_event.events=EPOLLIN;
00383 ep_event.data.ptr=e;
00384 again1:
00385 n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
00386 if (n==-1){
00387 if (errno==EAGAIN) goto again1;
00388 LM_ERR("epoll_ctl failed: %s [%d]\n",
00389 strerror(errno), errno);
00390 goto error;
00391 }
00392 break;
00393 case POLL_EPOLL_ET:
00394 set_fd_flags(O_NONBLOCK);
00395 ep_event.events=EPOLLIN|EPOLLET;
00396 ep_event.data.ptr=e;
00397 again2:
00398 n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
00399 if (n==-1){
00400 if (errno==EAGAIN) goto again2;
00401 LM_ERR("epoll_ctl failed: %s [%d]\n",
00402 strerror(errno), errno);
00403 goto error;
00404 }
00405 idx=-1;
00406 check_io=1;
00407 break;
00408 #endif
00409 #ifdef HAVE_KQUEUE
00410 case POLL_KQUEUE:
00411 if (kq_ev_change(h, fd, EVFILT_READ, EV_ADD, e)==-1)
00412 goto error;
00413 break;
00414 #endif
00415 #ifdef HAVE_DEVPOLL
00416 case POLL_DEVPOLL:
00417 pfd.fd=fd;
00418 pfd.events=POLLIN;
00419 pfd.revents=0;
00420 again_devpoll:
00421 if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){
00422 if (errno==EAGAIN) goto again_devpoll;
00423 LM_ERR("/dev/poll write failed:"
00424 "%s [%d]\n", strerror(errno), errno);
00425 goto error;
00426 }
00427 break;
00428 #endif
00429
00430 default:
00431 LM_CRIT("no support for poll method "
00432 " %s (%d)\n", poll_method_str[h->poll_method],
00433 h->poll_method);
00434 goto error;
00435 }
00436
00437 h->fd_no++;
00438
00439 #if defined(HAVE_SIGIO_RT) || defined (HAVE_EPOLL)
00440 if (check_io){
00441
00442 pf.fd=fd;
00443 pf.events=POLLIN;
00444 check_io_again:
00445 while( ((n=poll(&pf, 1, 0))>0) && (handle_io(e, idx)>0));
00446 if (n==-1){
00447 if (errno==EINTR) goto check_io_again;
00448 LM_ERR("check_io poll: %s [%d]\n",
00449 strerror(errno), errno);
00450 }
00451 }
00452 #endif
00453 return 0;
00454 error:
00455 if (e) unhash_fd_map(e);
00456 return -1;
00457 #undef fd_array_setup
00458 #undef set_fd_flags
00459 }
00460
00461
00462
00463 #define IO_FD_CLOSING 16
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags)
00480 {
00481
00482 #define fix_fd_array \
00483 do{\
00484 if (idx==-1){ \
00485 \
00486 for (idx=0; (idx<h->fd_no) && \
00487 (h->fd_array[idx].fd!=fd); idx++); \
00488 } \
00489 if (idx<h->fd_no){ \
00490 memmove(&h->fd_array[idx], &h->fd_array[idx+1], \
00491 (h->fd_no-(idx+1))*sizeof(*(h->fd_array))); \
00492 } \
00493 }while(0)
00494
00495 struct fd_map* e;
00496 #ifdef HAVE_EPOLL
00497 int n;
00498 struct epoll_event ep_event;
00499 #endif
00500 #ifdef HAVE_DEVPOLL
00501 struct pollfd pfd;
00502 #endif
00503 #ifdef HAVE_SIGIO_RT
00504 int fd_flags;
00505 #endif
00506
00507 if ((fd<0) || (fd>=h->max_fd_no)){
00508 LM_CRIT("invalid fd %d, not in [0, %d) \n", fd, h->fd_no);
00509 goto error;
00510 }
00511 LM_DBG("io_watch_del (%p, %d, %d, 0x%x) fd_no=%d called\n",
00512 h, fd, idx, flags, h->fd_no);
00513 e=get_fd_map(h, fd);
00514
00515 if (e==0){
00516 LM_CRIT("no corresponding hash entry for %d\n", fd);
00517 goto error;
00518 }
00519 if (e->type==0 ){
00520 LM_ERR("trying to delete already erased"
00521 " entry %d in the hash(%d, %d, %p) )\n",
00522 fd, e->fd, e->type, e->data);
00523 goto error;
00524 }
00525
00526 unhash_fd_map(e);
00527
00528 switch(h->poll_method){
00529 case POLL_POLL:
00530 fix_fd_array;
00531 break;
00532 #ifdef HAVE_SELECT
00533 case POLL_SELECT:
00534 fix_fd_array;
00535 FD_CLR(fd, &h->master_set);
00536 if (h->max_fd_select && (h->max_fd_select==fd))
00537
00538 h->max_fd_select--;
00539 break;
00540 #endif
00541 #ifdef HAVE_SIGIO_RT
00542 case POLL_SIGIO_RT:
00543 fix_fd_array;
00544
00545
00546
00547
00548
00549
00550
00551
00552 fd_flags=fcntl(fd, F_GETFL);
00553 if (fd_flags==-1){
00554 LM_ERR("fnctl: GETFL failed:"
00555 " %s [%d]\n", strerror(errno), errno);
00556 goto error;
00557 }
00558 if (fcntl(fd, F_SETFL, fd_flags&(~O_ASYNC))==-1){
00559 LM_ERR("fnctl: SETFL"
00560 " failed: %s [%d]\n", strerror(errno), errno);
00561 goto error;
00562 }
00563 break;
00564 #endif
00565 #ifdef HAVE_EPOLL
00566 case POLL_EPOLL_LT:
00567 case POLL_EPOLL_ET:
00568
00569
00570
00571
00572
00573 #ifdef EPOLL_NO_CLOSE_BUG
00574 if (!(flags & IO_FD_CLOSING)){
00575 #endif
00576 n=epoll_ctl(h->epfd, EPOLL_CTL_DEL, fd, &ep_event);
00577 if (n==-1){
00578 LM_ERR("removing fd from epoll "
00579 "list failed: %s [%d]\n", strerror(errno), errno);
00580 goto error;
00581 }
00582 #ifdef EPOLL_NO_CLOSE_BUG
00583 }
00584 #endif
00585 break;
00586 #endif
00587 #ifdef HAVE_KQUEUE
00588 case POLL_KQUEUE:
00589 if (!(flags & IO_FD_CLOSING)){
00590 if (kq_ev_change(h, fd, EVFILT_READ, EV_DELETE, 0)==-1)
00591 goto error;
00592 }
00593 break;
00594 #endif
00595 #ifdef HAVE_DEVPOLL
00596 case POLL_DEVPOLL:
00597
00598
00599 pfd.fd=fd;
00600 pfd.events=POLLREMOVE;
00601 pfd.revents=0;
00602 again_devpoll:
00603 if (write(h->dpoll_fd, &pfd, sizeof(pfd))==-1){
00604 if (errno==EINTR) goto again_devpoll;
00605 LM_ERR("removing fd from /dev/poll failed: "
00606 "%s [%d]\n", strerror(errno), errno);
00607 goto error;
00608 }
00609 break;
00610 #endif
00611 default:
00612 LM_CRIT("no support for poll method %s (%d)\n",
00613 poll_method_str[h->poll_method], h->poll_method);
00614 goto error;
00615 }
00616 h->fd_no--;
00617 return 0;
00618 error:
00619 return -1;
00620 #undef fix_fd_array
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 inline static int io_wait_loop_poll(io_wait_h* h, int t, int repeat)
00633 {
00634 int n, r;
00635 int ret;
00636 again:
00637 ret=n=poll(h->fd_array, h->fd_no, t*1000);
00638 if (n==-1){
00639 if (errno==EINTR) goto again;
00640 else{
00641 LM_ERR("poll: %s [%d]\n", strerror(errno), errno);
00642 goto error;
00643 }
00644 }
00645 for (r=0; (r<h->fd_no) && n; r++){
00646 if (h->fd_array[r].revents & (POLLIN|POLLERR|POLLHUP)){
00647 n--;
00648
00649 if ((h->fd_array[r].fd >= h->max_fd_no)||
00650 (h->fd_array[r].fd < 0)){
00651 LM_CRIT("bad fd %d (no in the 0 - %d range)\n",
00652 h->fd_array[r].fd, h->max_fd_no);
00653
00654 h->fd_array[r].events=0;
00655 continue;
00656 }
00657 while((handle_io(get_fd_map(h, h->fd_array[r].fd), r) > 0)
00658 && repeat);
00659 }
00660 }
00661 error:
00662 return ret;
00663 }
00664
00665
00666
00667 #ifdef HAVE_SELECT
00668
00669 inline static int io_wait_loop_select(io_wait_h* h, int t, int repeat)
00670 {
00671 fd_set sel_set;
00672 int n, ret;
00673 struct timeval timeout;
00674 int r;
00675
00676 again:
00677 sel_set=h->master_set;
00678 timeout.tv_sec=t;
00679 timeout.tv_usec=0;
00680 ret=n=select(h->max_fd_select+1, &sel_set, 0, 0, &timeout);
00681 if (n<0){
00682 if (errno==EINTR) goto again;
00683 LM_ERR("select: %s [%d]\n", strerror(errno), errno);
00684 n=0;
00685
00686 }
00687
00688 for(r=0; (r<h->max_fd_no) && n; r++){
00689 if (FD_ISSET(h->fd_array[r].fd, &sel_set)){
00690 while((handle_io(get_fd_map(h, h->fd_array[r].fd), r)>0)
00691 && repeat);
00692 n--;
00693 }
00694 };
00695 return ret;
00696 }
00697 #endif
00698
00699
00700
00701 #ifdef HAVE_EPOLL
00702 inline static int io_wait_loop_epoll(io_wait_h* h, int t, int repeat)
00703 {
00704 int n, r;
00705
00706 again:
00707 n=epoll_wait(h->epfd, h->ep_array, h->fd_no, t*1000);
00708 if (n==-1){
00709 if (errno==EINTR) goto again;
00710 else{
00711 LM_ERR("epoll_wait(%d, %p, %d, %d): %s [%d]\n",
00712 h->epfd, h->ep_array, h->fd_no, t*1000,
00713 strerror(errno), errno);
00714 goto error;
00715 }
00716 }
00717 #if 0
00718 if (n>1){
00719 for(r=0; r<n; r++){
00720 LM_ERR("ep_array[%d]= %x, %p\n",
00721 r, h->ep_array[r].events, h->ep_array[r].data.ptr);
00722 }
00723 }
00724 #endif
00725 for (r=0; r<n; r++){
00726 if (h->ep_array[r].events & (EPOLLIN|EPOLLERR|EPOLLHUP)){
00727 while((handle_io((struct fd_map*)h->ep_array[r].data.ptr,-1)>0)
00728 && repeat);
00729 }else{
00730 LM_ERR("unexpected event %x on %d/%d, data=%p\n",
00731 h->ep_array[r].events, r+1, n, h->ep_array[r].data.ptr);
00732 }
00733 }
00734 error:
00735 return n;
00736 }
00737 #endif
00738
00739
00740
00741 #ifdef HAVE_KQUEUE
00742 inline static int io_wait_loop_kqueue(io_wait_h* h, int t, int repeat)
00743 {
00744 int n, r;
00745 struct timespec tspec;
00746
00747 tspec.tv_sec=t;
00748 tspec.tv_nsec=0;
00749 again:
00750 n=kevent(h->kq_fd, h->kq_changes, h->kq_nchanges, h->kq_array,
00751 h->fd_no, &tspec);
00752 if (n==-1){
00753 if (errno==EINTR) goto again;
00754 else{
00755 LM_ERR("kevent: %s [%d]\n", strerror(errno), errno);
00756 goto error;
00757 }
00758 }
00759 h->kq_nchanges=0;
00760 for (r=0; r<n; r++){
00761 #ifdef EXTRA_DEBUG
00762 LM_DBG("event %d/%d: fd=%d, udata=%lx, flags=0x%x\n",
00763 r, n, h->kq_array[r].ident, (long)h->kq_array[r].udata,
00764 h->kq_array[r].flags);
00765 #endif
00766 if (h->kq_array[r].flags & EV_ERROR){
00767
00768
00769
00770
00771 LM_INFO("kevent error on fd %u: %s [%ld]\n",
00772 (unsigned int)h->kq_array[r].ident,
00773 strerror(h->kq_array[r].data),
00774 (long)h->kq_array[r].data);
00775 }else
00776 while((handle_io((struct fd_map*)h->kq_array[r].udata, -1)>0)
00777 && repeat);
00778 }
00779 error:
00780 return n;
00781 }
00782 #endif
00783
00784
00785
00786 #ifdef HAVE_SIGIO_RT
00787
00788 inline static int io_wait_loop_sigio_rt(io_wait_h* h, int t)
00789 {
00790 int n;
00791 int ret;
00792 struct timespec ts;
00793 siginfo_t siginfo;
00794 int sigio_band;
00795 int sigio_fd;
00796 struct fd_map* fm;
00797
00798
00799 ret=1;
00800 ts.tv_sec=t;
00801 ts.tv_nsec=0;
00802 if (!sigismember(&h->sset, h->signo) || !sigismember(&h->sset, SIGIO)){
00803 LM_CRIT("the signal mask is not properly set!\n");
00804 goto error;
00805 }
00806
00807 again:
00808 n=sigtimedwait(&h->sset, &siginfo, &ts);
00809 if (n==-1){
00810 if (errno==EINTR) goto again;
00811 else if (errno==EAGAIN){
00812 ret=0;
00813 goto end;
00814 }else{
00815 LM_ERR("sigtimed_wait %s [%d]\n", strerror(errno), errno);
00816 goto error;
00817 }
00818 }
00819 if (n!=SIGIO){
00820 #ifdef SIGINFO64_WORKARROUND
00821
00822
00823
00824
00825
00826
00827
00828 if (sizeof(siginfo.si_band)>sizeof(int)){
00829 sigio_band=*((int*)&siginfo.si_band);
00830 sigio_fd=*(((int*)&siginfo.si_band)+1);
00831 }else
00832 #endif
00833 {
00834 sigio_band=siginfo.si_band;
00835 sigio_fd=siginfo.si_fd;
00836 }
00837 if (siginfo.si_code==SI_SIGIO){
00838
00839 LM_WARN("old style sigio interface\n");
00840 fm=get_fd_map(h, sigio_fd);
00841
00842
00843 if (fm->type)
00844 handle_io(fm, -1);
00845 }else{
00846 #ifdef EXTRA_DEBUG
00847 LM_DBG("siginfo: signal=%d (%d),"
00848 " si_code=%d, si_band=0x%x,"
00849 " si_fd=%d\n",
00850 siginfo.si_signo, n, siginfo.si_code,
00851 (unsigned)sigio_band,
00852 sigio_fd);
00853 #endif
00854
00855
00856
00857 if (sigio_band){
00858 fm=get_fd_map(h, sigio_fd);
00859
00860
00861
00862 if (fm->type)
00863 handle_io(fm, -1);
00864 else
00865 LM_ERR("ignoring event"
00866 " %x on fd %d (fm->fd=%d, fm->data=%p)\n",
00867 sigio_band, sigio_fd, fm->fd, fm->data);
00868 }else{
00869 LM_ERR("unexpected event on fd %d: %x\n", sigio_fd, sigio_band);
00870 }
00871 }
00872 }else{
00873
00874
00875 LM_WARN("signal queue overflowed- falling back to poll\n");
00876
00877
00878
00879 if (signal(h->signo, SIG_IGN)==SIG_ERR){
00880 LM_CRIT("couldn't reset signal to IGN\n");
00881 }
00882
00883 if (signal(h->signo, SIG_DFL)==SIG_ERR){
00884 LM_CRIT("couldn't reset signal to DFL\n");
00885 }
00886
00887 ret=io_wait_loop_poll(h, -1, 1);
00888 }
00889 end:
00890 return ret;
00891 error:
00892 return -1;
00893 }
00894 #endif
00895
00896
00897
00898 #ifdef HAVE_DEVPOLL
00899 inline static int io_wait_loop_devpoll(io_wait_h* h, int t, int repeat)
00900 {
00901 int n, r;
00902 int ret;
00903 struct dvpoll dpoll;
00904
00905 dpoll.dp_timeout=t*1000;
00906 dpoll.dp_nfds=h->fd_no;
00907 dpoll.dp_fds=h->fd_array;
00908 again:
00909 ret=n=ioctl(h->dpoll_fd, DP_POLL, &dpoll);
00910 if (n==-1){
00911 if (errno==EINTR) goto again;
00912 else{
00913 LM_ERR("ioctl: %s [%d]\n", strerror(errno), errno);
00914 goto error;
00915 }
00916 }
00917 for (r=0; r< n; r++){
00918 if (h->fd_array[r].revents & (POLLNVAL|POLLERR)){
00919 LM_ERR("pollinval returned for fd %d, revents=%x\n",
00920 h->fd_array[r].fd, h->fd_array[r].revents);
00921 }
00922
00923 while((handle_io(get_fd_map(h, h->fd_array[r].fd), r) > 0) &&
00924 repeat);
00925 }
00926 error:
00927 return ret;
00928 }
00929 #endif
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 int init_io_wait(io_wait_h* h, int max_fd, enum poll_types poll_method);
00942
00943
00944 void destroy_io_wait(io_wait_h* h);
00945
00946
00947 #endif