Browse code

- automatically "listen" for POLLRDHUP or EPOLLRDHUP if supported (linux only)

Andrei Pelinescu-Onciul authored on 05/02/2008 21:37:28
Showing 1 changed files
... ...
@@ -43,6 +43,8 @@
43 43
  *  2007-11-22  when handle_io() is called in a loop check & stop if the fd was
44 44
  *               removed inside handle_io() (andrei)
45 45
  *  2007-11-29  support for write (POLLOUT); added io_watch_chg() (andrei)
46
+ *  2008-02-04  POLLRDHUP & EPOLLRDHUP support (automatically enabled if POLLIN
47
+ *               is set) (andrei)
46 48
  */
47 49
 
48 50
 
... ...
@@ -58,6 +60,11 @@
58 60
 #include <sys/socket.h> /* recv */
59 61
 #include <signal.h> /* sigprocmask, sigwait a.s.o */
60 62
 #endif
63
+
64
+#define _GNU_SOURCE  /* for POLLRDHUP on linux */
65
+#include <sys/poll.h>
66
+#include <fcntl.h>
67
+
61 68
 #ifdef HAVE_EPOLL
62 69
 #include <sys/epoll.h>
63 70
 #endif
... ...
@@ -77,8 +84,6 @@
77 84
 /* needed according to POSIX for select*/
78 85
 #include <sys/select.h>
79 86
 #endif
80
-#include <sys/poll.h>
81
-#include <fcntl.h>
82 87
 
83 88
 #include "dprint.h"
84 89
 
... ...
@@ -90,6 +95,14 @@
90 95
 #include "compiler_opt.h"
91 96
 
92 97
 
98
+#ifdef HAVE_EPOLL
99
+/* fix defines for EPOLL */
100
+#if defined POLLRDHUP && ! defined EPOLLRDHUP
101
+#define EPOLLRDHUP POLLRDHUP  /* should work on all linuxes */
102
+#endif /* POLLRDHUP && EPOLLRDHUP */
103
+#endif /* HAVE_EPOLL */
104
+
105
+
93 106
 extern int _os_ver; /* os version number, needed to select bugs workarrounds */
94 107
 
95 108
 
... ...
@@ -360,6 +373,10 @@ inline static int io_watch_add(	io_wait_h* h,
360 373
 	}
361 374
 	switch(h->poll_method){ /* faster then pointer to functions */
362 375
 		case POLL_POLL:
376
+#ifdef POLLRDHUP
377
+			/* listen to POLLRDHUP by default (if POLLIN) */
378
+			events|=((int)!(events & POLLIN) - 1) & POLLRDHUP;
379
+#endif /* POLLRDHUP */
363 380
 			fd_array_setup(events);
364 381
 			set_fd_flags(O_NONBLOCK);
365 382
 			break;
... ...
@@ -409,8 +426,14 @@ inline static int io_watch_add(	io_wait_h* h,
409 426
 #endif
410 427
 #ifdef HAVE_EPOLL
411 428
 		case POLL_EPOLL_LT:
412
-			ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
413
-							 (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
429
+			ep_event.events=
430
+#ifdef POLLRDHUP
431
+						/* listen for EPOLLRDHUP too */
432
+						((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
433
+#else /* POLLRDHUP */
434
+						(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
435
+#endif /* POLLRDHUP */
436
+						(EPOLLOUT & ((int)!(events & POLLOUT)-1) );
414 437
 			ep_event.data.ptr=e;
415 438
 again1:
416 439
 			n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
... ...
@@ -423,9 +446,15 @@ again1:
423 446
 			break;
424 447
 		case POLL_EPOLL_ET:
425 448
 			set_fd_flags(O_NONBLOCK);
426
-			ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) )  |
427
-							 (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
428
-							  EPOLLET;
449
+			ep_event.events=
450
+#ifdef POLLRDHUP
451
+						/* listen for EPOLLRDHUP too */
452
+						((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
453
+#else /* POLLRDHUP */
454
+						(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
455
+#endif /* POLLRDHUP */
456
+						(EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
457
+						EPOLLET;
429 458
 			ep_event.data.ptr=e;
430 459
 again2:
431 460
 			n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
... ...
@@ -754,6 +783,10 @@ inline static int io_watch_chg(io_wait_h* h, int fd, short events, int idx )
754 783
 	e->events=events;
755 784
 	switch(h->poll_method){
756 785
 		case POLL_POLL:
786
+#ifdef POLLRDHUP
787
+			/* listen to POLLRDHUP by default (if POLLIN) */
788
+			events|=((int)!(events & POLLIN) - 1) & POLLRDHUP;
789
+#endif /* POLLRDHUP */
757 790
 			fd_array_chg(events);
758 791
 			break;
759 792
 #ifdef HAVE_SELECT
... ...
@@ -778,8 +811,14 @@ inline static int io_watch_chg(io_wait_h* h, int fd, short events, int idx )
778 811
 #endif
779 812
 #ifdef HAVE_EPOLL
780 813
 		case POLL_EPOLL_LT:
781
-				ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
782
-								 (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
814
+				ep_event.events=
815
+#ifdef POLLRDHUP
816
+						/* listen for EPOLLRDHUP too */
817
+						((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
818
+#else /* POLLRDHUP */
819
+						(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
820
+#endif /* POLLRDHUP */
821
+						(EPOLLOUT & ((int)!(events & POLLOUT)-1) );
783 822
 				ep_event.data.ptr=e;
784 823
 again_epoll_lt:
785 824
 				n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
... ...
@@ -791,9 +830,15 @@ again_epoll_lt:
791 830
 				}
792 831
 			break;
793 832
 		case POLL_EPOLL_ET:
794
-				ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
795
-								 (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
796
-								 EPOLLET;
833
+				ep_event.events=
834
+#ifdef POLLRDHUP
835
+						/* listen for EPOLLRDHUP too */
836
+						((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
837
+#else /* POLLRDHUP */
838
+						(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
839
+#endif /* POLLRDHUP */
840
+						(EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
841
+						EPOLLET;
797 842
 				ep_event.data.ptr=e;
798 843
 again_epoll_et:
799 844
 				n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
... ...
@@ -1001,7 +1046,11 @@ again:
1001 1046
 						-1)) |
1002 1047
 					 (POLLOUT & (!(h->ep_array[r].events & EPOLLOUT)-1)) |
1003 1048
 					 (POLLERR & (!(h->ep_array[r].events & EPOLLERR)-1)) |
1004
-					 (POLLHUP & (!(h->ep_array[r].events & EPOLLHUP)-1));
1049
+					 (POLLHUP & (!(h->ep_array[r].events & EPOLLHUP)-1))
1050
+#ifdef POLLRDHUP
1051
+					| (POLLRDHUP & (!(h->ep_array[r].events & EPOLLRDHUP)-1))
1052
+#endif
1053
+					;
1005 1054
 			if (likely(revents)){
1006 1055
 				fm=(struct fd_map*)h->ep_array[r].data.ptr;
1007 1056
 				while(fm->type && ((fm->events|POLLERR|POLLHUP) & revents) &&