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 58
 #include <sys/socket.h> /* recv */
59 59
 #include <signal.h> /* sigprocmask, sigwait a.s.o */
60 60
 #endif
61
+
62
+#define _GNU_SOURCE  /* for POLLRDHUP on linux */
63
+#include <sys/poll.h>
64
+#include <fcntl.h>
65
+
61 66
 #ifdef HAVE_EPOLL
62 67
 #include <sys/epoll.h>
63 68
 #endif
... ...
@@ -77,8 +84,6 @@
77 77
 /* needed according to POSIX for select*/
78 78
 #include <sys/select.h>
79 79
 #endif
80
-#include <sys/poll.h>
81
-#include <fcntl.h>
82 80
 
83 81
 #include "dprint.h"
84 82
 
... ...
@@ -90,6 +95,14 @@
90 90
 #include "compiler_opt.h"
91 91
 
92 92
 
93
+#ifdef HAVE_EPOLL
94
+/* fix defines for EPOLL */
95
+#if defined POLLRDHUP && ! defined EPOLLRDHUP
96
+#define EPOLLRDHUP POLLRDHUP  /* should work on all linuxes */
97
+#endif /* POLLRDHUP && EPOLLRDHUP */
98
+#endif /* HAVE_EPOLL */
99
+
100
+
93 101
 extern int _os_ver; /* os version number, needed to select bugs workarrounds */
94 102
 
95 103
 
... ...
@@ -360,6 +373,10 @@ inline static int io_watch_add(	io_wait_h* h,
360 360
 	}
361 361
 	switch(h->poll_method){ /* faster then pointer to functions */
362 362
 		case POLL_POLL:
363
+#ifdef POLLRDHUP
364
+			/* listen to POLLRDHUP by default (if POLLIN) */
365
+			events|=((int)!(events & POLLIN) - 1) & POLLRDHUP;
366
+#endif /* POLLRDHUP */
363 367
 			fd_array_setup(events);
364 368
 			set_fd_flags(O_NONBLOCK);
365 369
 			break;
... ...
@@ -409,8 +426,14 @@ inline static int io_watch_add(	io_wait_h* h,
409 409
 #endif
410 410
 #ifdef HAVE_EPOLL
411 411
 		case POLL_EPOLL_LT:
412
-			ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
413
-							 (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
412
+			ep_event.events=
413
+#ifdef POLLRDHUP
414
+						/* listen for EPOLLRDHUP too */
415
+						((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
416
+#else /* POLLRDHUP */
417
+						(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
418
+#endif /* POLLRDHUP */
419
+						(EPOLLOUT & ((int)!(events & POLLOUT)-1) );
414 420
 			ep_event.data.ptr=e;
415 421
 again1:
416 422
 			n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
... ...
@@ -423,9 +446,15 @@ again1:
423 423
 			break;
424 424
 		case POLL_EPOLL_ET:
425 425
 			set_fd_flags(O_NONBLOCK);
426
-			ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) )  |
427
-							 (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
428
-							  EPOLLET;
426
+			ep_event.events=
427
+#ifdef POLLRDHUP
428
+						/* listen for EPOLLRDHUP too */
429
+						((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
430
+#else /* POLLRDHUP */
431
+						(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
432
+#endif /* POLLRDHUP */
433
+						(EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
434
+						EPOLLET;
429 435
 			ep_event.data.ptr=e;
430 436
 again2:
431 437
 			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 754
 	e->events=events;
755 755
 	switch(h->poll_method){
756 756
 		case POLL_POLL:
757
+#ifdef POLLRDHUP
758
+			/* listen to POLLRDHUP by default (if POLLIN) */
759
+			events|=((int)!(events & POLLIN) - 1) & POLLRDHUP;
760
+#endif /* POLLRDHUP */
757 761
 			fd_array_chg(events);
758 762
 			break;
759 763
 #ifdef HAVE_SELECT
... ...
@@ -778,8 +811,14 @@ inline static int io_watch_chg(io_wait_h* h, int fd, short events, int idx )
778 778
 #endif
779 779
 #ifdef HAVE_EPOLL
780 780
 		case POLL_EPOLL_LT:
781
-				ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
782
-								 (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
781
+				ep_event.events=
782
+#ifdef POLLRDHUP
783
+						/* listen for EPOLLRDHUP too */
784
+						((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
785
+#else /* POLLRDHUP */
786
+						(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
787
+#endif /* POLLRDHUP */
788
+						(EPOLLOUT & ((int)!(events & POLLOUT)-1) );
783 789
 				ep_event.data.ptr=e;
784 790
 again_epoll_lt:
785 791
 				n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
... ...
@@ -791,9 +830,15 @@ again_epoll_lt:
791 791
 				}
792 792
 			break;
793 793
 		case POLL_EPOLL_ET:
794
-				ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
795
-								 (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
796
-								 EPOLLET;
794
+				ep_event.events=
795
+#ifdef POLLRDHUP
796
+						/* listen for EPOLLRDHUP too */
797
+						((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
798
+#else /* POLLRDHUP */
799
+						(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
800
+#endif /* POLLRDHUP */
801
+						(EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
802
+						EPOLLET;
797 803
 				ep_event.data.ptr=e;
798 804
 again_epoll_et:
799 805
 				n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
... ...
@@ -1001,7 +1046,11 @@ again:
1001 1001
 						-1)) |
1002 1002
 					 (POLLOUT & (!(h->ep_array[r].events & EPOLLOUT)-1)) |
1003 1003
 					 (POLLERR & (!(h->ep_array[r].events & EPOLLERR)-1)) |
1004
-					 (POLLHUP & (!(h->ep_array[r].events & EPOLLHUP)-1));
1004
+					 (POLLHUP & (!(h->ep_array[r].events & EPOLLHUP)-1))
1005
+#ifdef POLLRDHUP
1006
+					| (POLLRDHUP & (!(h->ep_array[r].events & EPOLLRDHUP)-1))
1007
+#endif
1008
+					;
1005 1009
 			if (likely(revents)){
1006 1010
 				fm=(struct fd_map*)h->ep_array[r].data.ptr;
1007 1011
 				while(fm->type && ((fm->events|POLLERR|POLLHUP) & revents) &&