|
@@ -43,6 +43,8 @@
|
|
* 2007-11-22 when handle_io() is called in a loop check & stop if the fd was
|
|
* 2007-11-22 when handle_io() is called in a loop check & stop if the fd was
|
|
* removed inside handle_io() (andrei)
|
|
* removed inside handle_io() (andrei)
|
|
* 2007-11-29 support for write (POLLOUT); added io_watch_chg() (andrei)
|
|
* 2007-11-29 support for write (POLLOUT); added io_watch_chg() (andrei)
|
|
|
|
+ * 2008-02-04 POLLRDHUP & EPOLLRDHUP support (automatically enabled if POLLIN
|
|
|
|
+ * is set) (andrei)
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
|
|
@@ -58,6 +60,11 @@
|
|
#include <sys/socket.h> /* recv */
|
|
#include <sys/socket.h> /* recv */
|
|
#include <signal.h> /* sigprocmask, sigwait a.s.o */
|
|
#include <signal.h> /* sigprocmask, sigwait a.s.o */
|
|
#endif
|
|
#endif
|
|
|
|
+
|
|
|
|
+#define _GNU_SOURCE /* for POLLRDHUP on linux */
|
|
|
|
+#include <sys/poll.h>
|
|
|
|
+#include <fcntl.h>
|
|
|
|
+
|
|
#ifdef HAVE_EPOLL
|
|
#ifdef HAVE_EPOLL
|
|
#include <sys/epoll.h>
|
|
#include <sys/epoll.h>
|
|
#endif
|
|
#endif
|
|
@@ -77,8 +84,6 @@
|
|
/* needed according to POSIX for select*/
|
|
/* needed according to POSIX for select*/
|
|
#include <sys/select.h>
|
|
#include <sys/select.h>
|
|
#endif
|
|
#endif
|
|
-#include <sys/poll.h>
|
|
|
|
-#include <fcntl.h>
|
|
|
|
|
|
|
|
#include "dprint.h"
|
|
#include "dprint.h"
|
|
|
|
|
|
@@ -90,6 +95,14 @@
|
|
#include "compiler_opt.h"
|
|
#include "compiler_opt.h"
|
|
|
|
|
|
|
|
|
|
|
|
+#ifdef HAVE_EPOLL
|
|
|
|
+/* fix defines for EPOLL */
|
|
|
|
+#if defined POLLRDHUP && ! defined EPOLLRDHUP
|
|
|
|
+#define EPOLLRDHUP POLLRDHUP /* should work on all linuxes */
|
|
|
|
+#endif /* POLLRDHUP && EPOLLRDHUP */
|
|
|
|
+#endif /* HAVE_EPOLL */
|
|
|
|
+
|
|
|
|
+
|
|
extern int _os_ver; /* os version number, needed to select bugs workarrounds */
|
|
extern int _os_ver; /* os version number, needed to select bugs workarrounds */
|
|
|
|
|
|
|
|
|
|
@@ -360,6 +373,10 @@ inline static int io_watch_add( io_wait_h* h,
|
|
}
|
|
}
|
|
switch(h->poll_method){ /* faster then pointer to functions */
|
|
switch(h->poll_method){ /* faster then pointer to functions */
|
|
case POLL_POLL:
|
|
case POLL_POLL:
|
|
|
|
+#ifdef POLLRDHUP
|
|
|
|
+ /* listen to POLLRDHUP by default (if POLLIN) */
|
|
|
|
+ events|=((int)!(events & POLLIN) - 1) & POLLRDHUP;
|
|
|
|
+#endif /* POLLRDHUP */
|
|
fd_array_setup(events);
|
|
fd_array_setup(events);
|
|
set_fd_flags(O_NONBLOCK);
|
|
set_fd_flags(O_NONBLOCK);
|
|
break;
|
|
break;
|
|
@@ -409,8 +426,14 @@ inline static int io_watch_add( io_wait_h* h,
|
|
#endif
|
|
#endif
|
|
#ifdef HAVE_EPOLL
|
|
#ifdef HAVE_EPOLL
|
|
case POLL_EPOLL_LT:
|
|
case POLL_EPOLL_LT:
|
|
- ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
- (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
|
|
|
|
|
|
+ ep_event.events=
|
|
|
|
+#ifdef POLLRDHUP
|
|
|
|
+ /* listen for EPOLLRDHUP too */
|
|
|
|
+ ((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
+#else /* POLLRDHUP */
|
|
|
|
+ (EPOLLIN & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
+#endif /* POLLRDHUP */
|
|
|
|
+ (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
|
|
ep_event.data.ptr=e;
|
|
ep_event.data.ptr=e;
|
|
again1:
|
|
again1:
|
|
n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
|
|
n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
|
|
@@ -423,9 +446,15 @@ again1:
|
|
break;
|
|
break;
|
|
case POLL_EPOLL_ET:
|
|
case POLL_EPOLL_ET:
|
|
set_fd_flags(O_NONBLOCK);
|
|
set_fd_flags(O_NONBLOCK);
|
|
- ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
- (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
|
|
|
|
- EPOLLET;
|
|
|
|
|
|
+ ep_event.events=
|
|
|
|
+#ifdef POLLRDHUP
|
|
|
|
+ /* listen for EPOLLRDHUP too */
|
|
|
|
+ ((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
+#else /* POLLRDHUP */
|
|
|
|
+ (EPOLLIN & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
+#endif /* POLLRDHUP */
|
|
|
|
+ (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
|
|
|
|
+ EPOLLET;
|
|
ep_event.data.ptr=e;
|
|
ep_event.data.ptr=e;
|
|
again2:
|
|
again2:
|
|
n=epoll_ctl(h->epfd, EPOLL_CTL_ADD, fd, &ep_event);
|
|
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 )
|
|
e->events=events;
|
|
e->events=events;
|
|
switch(h->poll_method){
|
|
switch(h->poll_method){
|
|
case POLL_POLL:
|
|
case POLL_POLL:
|
|
|
|
+#ifdef POLLRDHUP
|
|
|
|
+ /* listen to POLLRDHUP by default (if POLLIN) */
|
|
|
|
+ events|=((int)!(events & POLLIN) - 1) & POLLRDHUP;
|
|
|
|
+#endif /* POLLRDHUP */
|
|
fd_array_chg(events);
|
|
fd_array_chg(events);
|
|
break;
|
|
break;
|
|
#ifdef HAVE_SELECT
|
|
#ifdef HAVE_SELECT
|
|
@@ -778,8 +811,14 @@ inline static int io_watch_chg(io_wait_h* h, int fd, short events, int idx )
|
|
#endif
|
|
#endif
|
|
#ifdef HAVE_EPOLL
|
|
#ifdef HAVE_EPOLL
|
|
case POLL_EPOLL_LT:
|
|
case POLL_EPOLL_LT:
|
|
- ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
- (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
|
|
|
|
|
|
+ ep_event.events=
|
|
|
|
+#ifdef POLLRDHUP
|
|
|
|
+ /* listen for EPOLLRDHUP too */
|
|
|
|
+ ((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
+#else /* POLLRDHUP */
|
|
|
|
+ (EPOLLIN & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
+#endif /* POLLRDHUP */
|
|
|
|
+ (EPOLLOUT & ((int)!(events & POLLOUT)-1) );
|
|
ep_event.data.ptr=e;
|
|
ep_event.data.ptr=e;
|
|
again_epoll_lt:
|
|
again_epoll_lt:
|
|
n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
|
|
n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
|
|
@@ -791,9 +830,15 @@ again_epoll_lt:
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case POLL_EPOLL_ET:
|
|
case POLL_EPOLL_ET:
|
|
- ep_event.events=(EPOLLIN & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
- (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
|
|
|
|
- EPOLLET;
|
|
|
|
|
|
+ ep_event.events=
|
|
|
|
+#ifdef POLLRDHUP
|
|
|
|
+ /* listen for EPOLLRDHUP too */
|
|
|
|
+ ((EPOLLIN|EPOLLRDHUP) & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
+#else /* POLLRDHUP */
|
|
|
|
+ (EPOLLIN & ((int)!(events & POLLIN)-1) ) |
|
|
|
|
+#endif /* POLLRDHUP */
|
|
|
|
+ (EPOLLOUT & ((int)!(events & POLLOUT)-1) ) |
|
|
|
|
+ EPOLLET;
|
|
ep_event.data.ptr=e;
|
|
ep_event.data.ptr=e;
|
|
again_epoll_et:
|
|
again_epoll_et:
|
|
n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
|
|
n=epoll_ctl(h->epfd, EPOLL_CTL_MOD, fd, &ep_event);
|
|
@@ -1001,7 +1046,11 @@ again:
|
|
-1)) |
|
|
-1)) |
|
|
(POLLOUT & (!(h->ep_array[r].events & EPOLLOUT)-1)) |
|
|
(POLLOUT & (!(h->ep_array[r].events & EPOLLOUT)-1)) |
|
|
(POLLERR & (!(h->ep_array[r].events & EPOLLERR)-1)) |
|
|
(POLLERR & (!(h->ep_array[r].events & EPOLLERR)-1)) |
|
|
- (POLLHUP & (!(h->ep_array[r].events & EPOLLHUP)-1));
|
|
|
|
|
|
+ (POLLHUP & (!(h->ep_array[r].events & EPOLLHUP)-1))
|
|
|
|
+#ifdef POLLRDHUP
|
|
|
|
+ | (POLLRDHUP & (!(h->ep_array[r].events & EPOLLRDHUP)-1))
|
|
|
|
+#endif
|
|
|
|
+ ;
|
|
if (likely(revents)){
|
|
if (likely(revents)){
|
|
fm=(struct fd_map*)h->ep_array[r].data.ptr;
|
|
fm=(struct fd_map*)h->ep_array[r].data.ptr;
|
|
while(fm->type && ((fm->events|POLLERR|POLLHUP) & revents) &&
|
|
while(fm->type && ((fm->events|POLLERR|POLLHUP) & revents) &&
|