Some applications may create the kqueue/epoll descriptor after
creating (many) other descriptors. ppoll() provides consistent
performance and memory usage for high-numbered file descriptors
in this case.
ppoll() has been available since Linux 2.6.16, however we
already depend on eventfd() which came in Linux 2.6.22.
---
Downloadable from:
http://bogomips.org/libkqueue.git/patch?id=222e95c6b3
src/linux/platform.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/linux/platform.c b/src/linux/platform.c
index cb118da..82830be 100644
--- a/src/linux/platform.c
+++ b/src/linux/platform.c
@@ -14,6 +14,8 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+# define _GNU_SOURCE
+# include <poll.h>
#include "../common/private.h"
//XXX-FIXME TEMP
@@ -90,16 +92,15 @@ linux_kevent_wait_hires(
struct kqueue *kq,
const struct timespec *timeout)
{
- fd_set fds;
int n;
- int epfd;
+ struct pollfd fds;
dbg_printf("waiting for events (timeout=%ld sec %ld nsec)",
timeout->tv_sec, timeout->tv_nsec);
- epfd = kqueue_epfd(kq);
- FD_ZERO(&fds);
- FD_SET(epfd, &fds);
- n = pselect(epfd + 1, &fds, NULL , NULL, timeout, NULL);
+ fds.fd = kqueue_epfd(kq);
+ fds.events = POLLIN;
+
+ n = ppoll(&fds, 1, timeout, NULL);
if (n < 0) {
if (errno == EINTR) {
dbg_puts("signal caught");
@@ -120,13 +121,13 @@ linux_kevent_wait(
{
int timeout, nret;
- /* Use pselect() if the timeout value is less than one millisecond. */
+ /* Use ppoll() if the timeout value is less than one millisecond. */
if (ts != NULL && ts->tv_sec == 0 && ts->tv_nsec > 0 && ts->tv_nsec < 1000000) {
nret = linux_kevent_wait_hires(kq, ts);
if (nret <= 0)
return (nret);
- /* pselect() told us epoll_wait() should have ready events */
+ /* ppoll() told us epoll_wait() should have ready events */
timeout = 0;
} else {
/* Convert timeout to the format used by epoll_wait() */
--
Eric Wong