... | ... |
@@ -57,7 +57,7 @@ MAIN_NAME=ser |
57 | 57 |
VERSION = 0 |
58 | 58 |
PATCHLEVEL = 10 |
59 | 59 |
SUBLEVEL = 99 |
60 |
-EXTRAVERSION = -dev10 |
|
60 |
+EXTRAVERSION = -dev11-tcp |
|
61 | 61 |
|
62 | 62 |
RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) |
63 | 63 |
OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]") |
... | ... |
@@ -297,13 +297,19 @@ inline static int io_watch_add( io_wait_h* h, |
297 | 297 |
int n; |
298 | 298 |
struct epoll_event ep_event; |
299 | 299 |
#endif |
300 |
-#ifdef HAVE_SIGIO_RT |
|
301 |
- static char buf[65536]; |
|
302 |
-#endif |
|
303 | 300 |
#ifdef HAVE_DEVPOLL |
304 | 301 |
struct pollfd pfd; |
305 | 302 |
#endif |
303 |
+#if defined(HAVE_SIGIO_RT) || defined (HAVE_EPOLL) |
|
304 |
+ int idx; |
|
305 |
+ int check_io; |
|
306 |
+ struct pollfd pf; |
|
306 | 307 |
|
308 |
+ check_io=0; /* set to 1 if we need to check for pre-existiing queued |
|
309 |
+ io/data on the fd */ |
|
310 |
+ idx=-1; |
|
311 |
+#endif |
|
312 |
+ e=0; |
|
307 | 313 |
if (fd==-1){ |
308 | 314 |
LOG(L_CRIT, "BUG: io_watch_add: fd is -1!\n"); |
309 | 315 |
goto error; |
... | ... |
@@ -344,6 +350,10 @@ inline static int io_watch_add( io_wait_h* h, |
344 | 350 |
#ifdef HAVE_SIGIO_RT |
345 | 351 |
case POLL_SIGIO_RT: |
346 | 352 |
fd_array_setup; |
353 |
+ /* re-set O_ASYNC might be needed, if not done from |
|
354 |
+ * io_watch_del (or if somebody wants to add a fd which has |
|
355 |
+ * already O_ASYNC/F_SETSIG set on a dupplicate) |
|
356 |
+ */ |
|
347 | 357 |
/* set async & signal */ |
348 | 358 |
if (fcntl(fd, F_SETOWN, my_pid())==-1){ |
349 | 359 |
LOG(L_ERR, "ERROR: io_watch_add: fnctl: SETOWN" |
... | ... |
@@ -362,9 +372,13 @@ inline static int io_watch_add( io_wait_h* h, |
362 | 372 |
fd, h->signo, my_pid()); |
363 | 373 |
#endif |
364 | 374 |
/* empty socket receive buffer, if buffer is already full |
365 |
- * (e.g. early media), no more space to put packets |
|
366 |
- * => no more signals are ever generated -- andrei */ |
|
367 |
- while(recv(fd, buf, sizeof(buf), 0)>=0); |
|
375 |
+ * no more space to put packets |
|
376 |
+ * => no more signals are ever generated |
|
377 |
+ * also when moving fds, the freshly moved fd might have |
|
378 |
+ * already some bytes queued, we want to get them now |
|
379 |
+ * and not later -- andrei */ |
|
380 |
+ idx=h->fd_no; |
|
381 |
+ check_io=1; |
|
368 | 382 |
break; |
369 | 383 |
#endif |
370 | 384 |
#ifdef HAVE_EPOLL |
... | ... |
@@ -392,6 +406,8 @@ again2: |
392 | 406 |
strerror(errno), errno); |
393 | 407 |
goto error; |
394 | 408 |
} |
409 |
+ idx=-1; |
|
410 |
+ check_io=1; |
|
395 | 411 |
break; |
396 | 412 |
#endif |
397 | 413 |
#ifdef HAVE_KQUEUE |
... | ... |
@@ -424,8 +440,23 @@ again_devpoll: |
424 | 440 |
|
425 | 441 |
h->fd_no++; /* "activate" changes, for epoll/kqueue/devpoll it |
426 | 442 |
has only informative value */ |
443 |
+#if defined(HAVE_SIGIO_RT) || defined (HAVE_EPOLL) |
|
444 |
+ if (check_io){ |
|
445 |
+ /* handle possible pre-existing events */ |
|
446 |
+ pf.fd=fd; |
|
447 |
+ pf.events=POLLIN; |
|
448 |
+check_io_again: |
|
449 |
+ while( ((n=poll(&pf, 1, 0))>0) && (handle_io(e, idx)>0)); |
|
450 |
+ if (n==-1){ |
|
451 |
+ if (errno==EINTR) goto check_io_again; |
|
452 |
+ LOG(L_ERR, "ERROR: io_watch_add: check_io poll: %s [%d]\n", |
|
453 |
+ strerror(errno), errno); |
|
454 |
+ } |
|
455 |
+ } |
|
456 |
+#endif |
|
427 | 457 |
return 0; |
428 | 458 |
error: |
459 |
+ if (e) unhash_fd_map(e); |
|
429 | 460 |
return -1; |
430 | 461 |
#undef fd_array_setup |
431 | 462 |
#undef set_fd_flags |
... | ... |
@@ -469,14 +500,17 @@ inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags) |
469 | 500 |
#ifdef HAVE_DEVPOLL |
470 | 501 |
struct pollfd pfd; |
471 | 502 |
#endif |
503 |
+#ifdef HAVE_SIGIO_RT |
|
504 |
+ int fd_flags; |
|
505 |
+#endif |
|
472 | 506 |
|
473 | 507 |
if ((fd<0) || (fd>=h->max_fd_no)){ |
474 | 508 |
LOG(L_CRIT, "BUG: io_watch_del: invalid fd %d, not in [0, %d) \n", |
475 | 509 |
fd, h->fd_no); |
476 | 510 |
goto error; |
477 | 511 |
} |
478 |
- DBG("DBG: io_watch_del (%p, %d, %d) fd_no=%d called\n", |
|
479 |
- h, fd, idx, h->fd_no); |
|
512 |
+ DBG("DBG: io_watch_del (%p, %d, %d, 0x%x) fd_no=%d called\n", |
|
513 |
+ h, fd, idx, flags, h->fd_no); |
|
480 | 514 |
e=get_fd_map(h, fd); |
481 | 515 |
/* more sanity checks */ |
482 | 516 |
if (e==0){ |
... | ... |
@@ -509,25 +543,47 @@ inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags) |
509 | 543 |
#ifdef HAVE_SIGIO_RT |
510 | 544 |
case POLL_SIGIO_RT: |
511 | 545 |
fix_fd_array; |
512 |
- /* FIXME: re-set ASYNC? (not needed if the fd is/will be closed |
|
513 |
- * but might cause problems if the fd is "moved") |
|
514 |
- * update: probably not needed, the fd_map type!=0 |
|
515 |
- * check should catch old queued signals or in-transit fd |
|
516 |
- * (so making another syscall to reset ASYNC is not |
|
517 |
- * necessary)*/ |
|
546 |
+ /* the O_ASYNC flag must be reset all the time, the fd |
|
547 |
+ * can be changed only if O_ASYNC is reset (if not and |
|
548 |
+ * the fd is a duplicate, you will get signals from the dup. fd |
|
549 |
+ * and not from the original, even if the dup. fd wa closed |
|
550 |
+ * and the signals re-set on the original) -- andrei |
|
551 |
+ */ |
|
552 |
+ /*if (!(flags & IO_FD_CLOSING)){*/ |
|
553 |
+ /* reset ASYNC */ |
|
554 |
+ fd_flags=fcntl(fd, F_GETFL); |
|
555 |
+ if (fd_flags==-1){ |
|
556 |
+ LOG(L_ERR, "ERROR: io_watch_del: fnctl: GETFL failed:" |
|
557 |
+ " %s [%d]\n", strerror(errno), errno); |
|
558 |
+ goto error; |
|
559 |
+ } |
|
560 |
+ if (fcntl(fd, F_SETFL, fd_flags&(~O_ASYNC))==-1){ |
|
561 |
+ LOG(L_ERR, "ERROR: io_watch_del: fnctl: SETFL" |
|
562 |
+ " failed: %s [%d]\n", strerror(errno), errno); |
|
563 |
+ goto error; |
|
564 |
+ } |
|
518 | 565 |
break; |
519 | 566 |
#endif |
520 | 567 |
#ifdef HAVE_EPOLL |
521 | 568 |
case POLL_EPOLL_LT: |
522 | 569 |
case POLL_EPOLL_ET: |
570 |
+ /* epoll doesn't seem to automatically remove sockets, |
|
571 |
+ * if the socket is a dupplicate/moved and the original |
|
572 |
+ * is still open. The fd is removed from the epoll set |
|
573 |
+ * only when the original (and all the copies?) is/are |
|
574 |
+ * closed. This is probably a bug in epoll. --andrei */ |
|
575 |
+#ifdef EPOLL_NO_CLOSE_BUG |
|
523 | 576 |
if (!(flags & IO_FD_CLOSING)){ |
577 |
+#endif |
|
524 | 578 |
n=epoll_ctl(h->epfd, EPOLL_CTL_DEL, fd, &ep_event); |
525 | 579 |
if (n==-1){ |
526 | 580 |
LOG(L_ERR, "ERROR: io_watch_del: removing fd from epoll " |
527 | 581 |
"list failed: %s [%d]\n", strerror(errno), errno); |
528 | 582 |
goto error; |
529 | 583 |
} |
584 |
+#ifdef EPOLL_NO_CLOSE_BUG |
|
530 | 585 |
} |
586 |
+#endif |
|
531 | 587 |
break; |
532 | 588 |
#endif |
533 | 589 |
#ifdef HAVE_KQUEUE |
... | ... |
@@ -659,8 +715,10 @@ again: |
659 | 715 |
if (n==-1){ |
660 | 716 |
if (errno==EINTR) goto again; /* signal, ignore it */ |
661 | 717 |
else{ |
662 |
- LOG(L_ERR, "ERROR:io_wait_loop_epoll: epoll_wait:" |
|
663 |
- " %s [%d]\n", strerror(errno), errno); |
|
718 |
+ LOG(L_ERR, "ERROR:io_wait_loop_epoll: " |
|
719 |
+ "epoll_wait(%d, %p, %d, %d): %s [%d]\n", |
|
720 |
+ h->epfd, h->ep_array, h->fd_no, t*1000, |
|
721 |
+ strerror(errno), errno); |
|
664 | 722 |
goto error; |
665 | 723 |
} |
666 | 724 |
} |
... | ... |
@@ -1174,10 +1174,11 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i) |
1174 | 1174 |
tcpconn_destroy(tcpconn); |
1175 | 1175 |
break; |
1176 | 1176 |
} |
1177 |
- io_watch_add(&io_h, tcpconn->s, F_TCPCONN, tcpconn); |
|
1178 | 1177 |
/* update the timeout*/ |
1179 | 1178 |
tcpconn->timeout=get_ticks()+TCP_CON_TIMEOUT; |
1180 | 1179 |
tcpconn_put(tcpconn); |
1180 |
+ /* must be after the de-ref*/ |
|
1181 |
+ io_watch_add(&io_h, tcpconn->s, F_TCPCONN, tcpconn); |
|
1181 | 1182 |
DBG("handle_tcp_child: CONN_RELEASE %p refcnt= %d\n", |
1182 | 1183 |
tcpconn, tcpconn->refcnt); |
1183 | 1184 |
break; |
... | ... |
@@ -1309,9 +1310,9 @@ inline static int handle_ser_child(struct process_table* p, int fd_i) |
1309 | 1310 |
tcpconn->s=fd; |
1310 | 1311 |
/* add tcpconn to the list*/ |
1311 | 1312 |
tcpconn_add(tcpconn); |
1312 |
- io_watch_add(&io_h, tcpconn->s, F_TCPCONN, tcpconn); |
|
1313 | 1313 |
/* update the timeout*/ |
1314 | 1314 |
tcpconn->timeout=get_ticks()+TCP_CON_TIMEOUT; |
1315 |
+ io_watch_add(&io_h, tcpconn->s, F_TCPCONN, tcpconn); |
|
1315 | 1316 |
break; |
1316 | 1317 |
default: |
1317 | 1318 |
LOG(L_CRIT, "BUG: handle_ser_child: unknown cmd %d\n", cmd); |
... | ... |
@@ -33,6 +33,7 @@ |
33 | 33 |
* 2003-07-01 tcp_read & friends take no a single tcp_connection |
34 | 34 |
* parameter & they set c->state to S_CONN_EOF on eof (andrei) |
35 | 35 |
* 2003-07-04 fixed tcp EOF handling (possible infinite loop) (andrei) |
36 |
+ * 2005-07-05 migrated to the new io_wait code (andrei) |
|
36 | 37 |
*/ |
37 | 38 |
|
38 | 39 |
#ifdef USE_TCP |
... | ... |
@@ -62,6 +63,17 @@ |
62 | 63 |
#include "tls/tls_server.h" |
63 | 64 |
#endif |
64 | 65 |
|
66 |
+#define HANDLE_IO_INLINE |
|
67 |
+#include "io_wait.h" |
|
68 |
+#include <fcntl.h> /* must be included after io_wait.h if SIGIO_RT is used */ |
|
69 |
+ |
|
70 |
+/* types used in io_wait* */ |
|
71 |
+enum fd_types { F_NONE, F_TCPMAIN, F_TCPCONN }; |
|
72 |
+ |
|
73 |
+/* list of tcp connections handled by this process */ |
|
74 |
+static struct tcp_connection* tcp_conn_lst=0; |
|
75 |
+static io_wait_h io_w; /* io_wait handler*/ |
|
76 |
+static int tcpmain_sock=-1; |
|
65 | 77 |
|
66 | 78 |
|
67 | 79 |
/* reads next available bytes |
... | ... |
@@ -385,7 +397,7 @@ skip: |
385 | 397 |
|
386 | 398 |
|
387 | 399 |
|
388 |
-int tcp_read_req(struct tcp_connection* con) |
|
400 |
+int tcp_read_req(struct tcp_connection* con, int* bytes_read) |
|
389 | 401 |
{ |
390 | 402 |
int bytes; |
391 | 403 |
int resp; |
... | ... |
@@ -394,6 +406,7 @@ int tcp_read_req(struct tcp_connection* con) |
394 | 406 |
int s; |
395 | 407 |
char c; |
396 | 408 |
|
409 |
+ bytes=-1; |
|
397 | 410 |
resp=CONN_RELEASE; |
398 | 411 |
s=con->fd; |
399 | 412 |
req=&con->req; |
... | ... |
@@ -520,7 +533,7 @@ again: |
520 | 533 |
|
521 | 534 |
|
522 | 535 |
end_req: |
523 |
- |
|
536 |
+ if (bytes_read) *bytes_read=bytes; |
|
524 | 537 |
return resp; |
525 | 538 |
} |
526 | 539 |
|
... | ... |
@@ -543,7 +556,8 @@ void release_tcpconn(struct tcp_connection* c, long state, int unix_sock) |
543 | 556 |
} |
544 | 557 |
|
545 | 558 |
|
546 |
- |
|
559 |
+#ifdef DEBUG_TCP_RECEIVE |
|
560 |
+/* old code known to work, kept arround for debuging */ |
|
547 | 561 |
void tcp_receive_loop(int unix_sock) |
548 | 562 |
{ |
549 | 563 |
struct tcp_connection* list; /* list with connections in use */ |
... | ... |
@@ -680,15 +694,229 @@ skip: |
680 | 694 |
|
681 | 695 |
} |
682 | 696 |
} |
697 |
+#else /* DEBUG_TCP_RECEIVE */ |
|
698 |
+ |
|
699 |
+ |
|
700 |
+ |
|
701 |
+/* handle io routine, based on the fd_map type |
|
702 |
+ * (it will be called from io_wait_loop* ) |
|
703 |
+ * params: fm - pointer to a fd hash entry |
|
704 |
+ * idx - index in the fd_array (or -1 if not known) |
|
705 |
+ * return: -1 on error, or when we are not interested any more on reads |
|
706 |
+ * from this fd (e.g.: we are closing it ) |
|
707 |
+ * 0 on EAGAIN or when by some other way it is known that no more |
|
708 |
+ * io events are queued on the fd (the receive buffer is empty). |
|
709 |
+ * Usefull to detect when there are no more io events queued for |
|
710 |
+ * sigio_rt, epoll_et, kqueue. |
|
711 |
+ * >0 on successfull read from the fd (when there might be more io |
|
712 |
+ * queued -- the receive buffer might still be non-empty) |
|
713 |
+ */ |
|
714 |
+inline static int handle_io(struct fd_map* fm, int idx) |
|
715 |
+{ |
|
716 |
+ int ret; |
|
717 |
+ int n; |
|
718 |
+ struct tcp_connection* con; |
|
719 |
+ int s; |
|
720 |
+ long resp; |
|
721 |
+ |
|
722 |
+ switch(fm->type){ |
|
723 |
+ case F_TCPMAIN: |
|
724 |
+again: |
|
725 |
+ ret=n=receive_fd(fm->fd, &con, sizeof(con), &s, 0); |
|
726 |
+ DBG("received n=%d con=%p, fd=%d\n", n, con, s); |
|
727 |
+ if (n<0){ |
|
728 |
+ if (errno == EWOULDBLOCK || errno == EAGAIN){ |
|
729 |
+ ret=0; |
|
730 |
+ break; |
|
731 |
+ }else if (errno == EINTR) goto again; |
|
732 |
+ else{ |
|
733 |
+ LOG(L_CRIT,"BUG: tcp_receive: handle_io: read_fd: %s \n", |
|
734 |
+ strerror(errno)); |
|
735 |
+ abort(); /* big error*/ |
|
736 |
+ } |
|
737 |
+ } |
|
738 |
+ if (n==0){ |
|
739 |
+ LOG(L_ERR, "WARNING: tcp_receive: handle_io: 0 bytes read\n"); |
|
740 |
+ break; |
|
741 |
+ } |
|
742 |
+ if (con==0){ |
|
743 |
+ LOG(L_CRIT, "BUG: tcp_receive: handle_io null pointer\n"); |
|
744 |
+ break; |
|
745 |
+ } |
|
746 |
+ con->fd=s; |
|
747 |
+ if (s==-1) { |
|
748 |
+ LOG(L_ERR, "ERROR: tcp_receive: handle_io: read_fd:" |
|
749 |
+ "no fd read\n"); |
|
750 |
+ goto con_error; |
|
751 |
+ } |
|
752 |
+ if (con==tcp_conn_lst){ |
|
753 |
+ LOG(L_CRIT, "BUG: tcp_receive: handle_io: duplicate" |
|
754 |
+ " connection received: %p, id %d, fd %d, refcnt %d" |
|
755 |
+ " state %d (n=%d)\n", con, con->id, con->fd, |
|
756 |
+ con->refcnt, con->state, n); |
|
757 |
+ release_tcpconn(con, CONN_ERROR, tcpmain_sock); |
|
758 |
+ break; /* try to recover */ |
|
759 |
+ } |
|
760 |
+ /* must be before io_watch_add, io_watch_add might catch some |
|
761 |
+ * already existing events => might call handle_io and |
|
762 |
+ * handle_io might decide to del. the new connection => |
|
763 |
+ * must be in the list */ |
|
764 |
+ tcpconn_listadd(tcp_conn_lst, con, c_next, c_prev); |
|
765 |
+ con->timeout=get_ticks()+TCP_CHILD_TIMEOUT; |
|
766 |
+ if (io_watch_add(&io_w, s, F_TCPCONN, con)<0){ |
|
767 |
+ LOG(L_CRIT, "ERROR: tcp_receive: handle_io: failed to add" |
|
768 |
+ " new socket to the fd list\n"); |
|
769 |
+ tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev); |
|
770 |
+ goto con_error; |
|
771 |
+ } |
|
772 |
+ break; |
|
773 |
+ case F_TCPCONN: |
|
774 |
+ con=(struct tcp_connection*)fm->data; |
|
775 |
+ resp=tcp_read_req(con, &ret); |
|
776 |
+ if (resp<0){ |
|
777 |
+ ret=-1; /* some error occured */ |
|
778 |
+ io_watch_del(&io_w, con->fd, idx, IO_FD_CLOSING); |
|
779 |
+ tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev); |
|
780 |
+ con->state=S_CONN_BAD; |
|
781 |
+ release_tcpconn(con, resp, tcpmain_sock); |
|
782 |
+ }else{ |
|
783 |
+ /* update timeout */ |
|
784 |
+ con->timeout=get_ticks()+TCP_CHILD_TIMEOUT; |
|
785 |
+ } |
|
786 |
+ break; |
|
787 |
+ case F_NONE: |
|
788 |
+ LOG(L_CRIT, "BUG: handle_io: empty fd map %p (%d): " |
|
789 |
+ "{%d, %d, %p}\n", fm, (int)(fm-io_w.fd_hash), |
|
790 |
+ fm->fd, fm->type, fm->data); |
|
791 |
+ goto error; |
|
792 |
+ default: |
|
793 |
+ LOG(L_CRIT, "BUG: handle_io: uknown fd type %d\n", fm->type); |
|
794 |
+ goto error; |
|
795 |
+ } |
|
796 |
+ |
|
797 |
+ return ret; |
|
798 |
+con_error: |
|
799 |
+ con->state=S_CONN_BAD; |
|
800 |
+ release_tcpconn(con, CONN_ERROR, fm->fd); |
|
801 |
+ return ret; |
|
802 |
+error: |
|
803 |
+ return -1; |
|
804 |
+} |
|
683 | 805 |
|
684 | 806 |
|
685 |
-#if 0 |
|
686 |
-int main(int argv, char** argc ) |
|
807 |
+ |
|
808 |
+/* releases expired connections and cleans up bad ones (state<0) */ |
|
809 |
+static inline void tcp_receive_timeout() |
|
687 | 810 |
{ |
688 |
- printf("starting tests\n"); |
|
689 |
- tcp_receive_loop(); |
|
811 |
+ struct tcp_connection* con; |
|
812 |
+ struct tcp_connection* next; |
|
813 |
+ int ticks; |
|
814 |
+ |
|
815 |
+ ticks=get_ticks(); |
|
816 |
+ for (con=tcp_conn_lst; con; con=next){ |
|
817 |
+ next=con->c_next; /* safe for removing */ |
|
818 |
+ if (con->state<0){ /* kill bad connections */ |
|
819 |
+ /* S_CONN_BAD or S_CONN_ERROR, remove it */ |
|
820 |
+ /* fd will be closed in release_tcpconn */ |
|
821 |
+ io_watch_del(&io_w, con->fd, -1, IO_FD_CLOSING); |
|
822 |
+ tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev); |
|
823 |
+ con->state=S_CONN_BAD; |
|
824 |
+ release_tcpconn(con, CONN_ERROR, tcpmain_sock); |
|
825 |
+ continue; |
|
826 |
+ } |
|
827 |
+ if (con->timeout<=ticks){ |
|
828 |
+ /* expired, return to "tcp main" */ |
|
829 |
+ DBG("tcp_receive_loop: %p expired (%d, %d)\n", |
|
830 |
+ con, con->timeout, ticks); |
|
831 |
+ /* fd will be closed in release_tcpconn */ |
|
832 |
+ io_watch_del(&io_w, con->fd, -1, IO_FD_CLOSING); |
|
833 |
+ tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev); |
|
834 |
+ release_tcpconn(con, CONN_RELEASE, tcpmain_sock); |
|
835 |
+ } |
|
836 |
+ } |
|
690 | 837 |
} |
691 | 838 |
|
692 |
-#endif |
|
693 | 839 |
|
840 |
+ |
|
841 |
+void tcp_receive_loop(int unix_sock) |
|
842 |
+{ |
|
843 |
+ |
|
844 |
+ /* init */ |
|
845 |
+ tcpmain_sock=unix_sock; /* init com. socket */ |
|
846 |
+ if (init_io_wait(&io_w, tcp_max_fd_no, tcp_poll_method)<0) |
|
847 |
+ goto error; |
|
848 |
+ /* add the unix socket */ |
|
849 |
+ if (io_watch_add(&io_w, tcpmain_sock, F_TCPMAIN, 0)<0){ |
|
850 |
+ LOG(L_CRIT, "ERROR: tcp_receive_loop: init: failed to add socket " |
|
851 |
+ " to the fd list\n"); |
|
852 |
+ goto error; |
|
853 |
+ } |
|
854 |
+ /* main loop */ |
|
855 |
+ switch(io_w.poll_method){ |
|
856 |
+ case POLL_POLL: |
|
857 |
+ while(1){ |
|
858 |
+ io_wait_loop_poll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0); |
|
859 |
+ tcp_receive_timeout(); |
|
860 |
+ } |
|
861 |
+ break; |
|
862 |
+#ifdef HAVE_SELECT |
|
863 |
+ case POLL_SELECT: |
|
864 |
+ while(1){ |
|
865 |
+ io_wait_loop_select(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0); |
|
866 |
+ tcp_receive_timeout(); |
|
867 |
+ } |
|
868 |
+ break; |
|
869 |
+#endif |
|
870 |
+#ifdef HAVE_SIGIO_RT |
|
871 |
+ case POLL_SIGIO_RT: |
|
872 |
+ while(1){ |
|
873 |
+ io_wait_loop_sigio_rt(&io_w, TCP_CHILD_SELECT_TIMEOUT); |
|
874 |
+ tcp_receive_timeout(); |
|
875 |
+ } |
|
876 |
+ break; |
|
877 |
+#endif |
|
878 |
+#ifdef HAVE_EPOLL |
|
879 |
+ case POLL_EPOLL_LT: |
|
880 |
+ while(1){ |
|
881 |
+ io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0); |
|
882 |
+ tcp_receive_timeout(); |
|
883 |
+ } |
|
884 |
+ break; |
|
885 |
+ case POLL_EPOLL_ET: |
|
886 |
+ while(1){ |
|
887 |
+ io_wait_loop_epoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 1); |
|
888 |
+ tcp_receive_timeout(); |
|
889 |
+ } |
|
890 |
+ break; |
|
694 | 891 |
#endif |
892 |
+#ifdef HAVE_KQUEUE |
|
893 |
+ case POLL_KQUEUE: |
|
894 |
+ while(1){ |
|
895 |
+ io_wait_loop_kqueue(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0); |
|
896 |
+ tcp_receive_timeout(); |
|
897 |
+ } |
|
898 |
+ break; |
|
899 |
+#endif |
|
900 |
+#ifdef HAVE_DEVPOLL |
|
901 |
+ case POLL_DEVPOLL: |
|
902 |
+ while(1){ |
|
903 |
+ io_wait_loop_devpoll(&io_w, TCP_CHILD_SELECT_TIMEOUT, 0); |
|
904 |
+ tcp_receive_timeout(); |
|
905 |
+ } |
|
906 |
+ break; |
|
907 |
+#endif |
|
908 |
+ default: |
|
909 |
+ LOG(L_CRIT, "BUG: tcp_receive_loop: no support for poll method " |
|
910 |
+ " %s (%d)\n", |
|
911 |
+ poll_method_name(io_w.poll_method), io_w.poll_method); |
|
912 |
+ goto error; |
|
913 |
+ } |
|
914 |
+error: |
|
915 |
+ destroy_io_wait(&io_w); |
|
916 |
+ LOG(L_CRIT, "ERROR: tcp_receive_loop: exiting..."); |
|
917 |
+ exit(-1); |
|
918 |
+} |
|
919 |
+ |
|
920 |
+#endif /* DEBUG_TCP_RECEIVE */ |
|
921 |
+ |
|
922 |
+#endif /* USE_TCP */ |