1
0
mirror of https://github.com/rkd77/elinks.git synced 2025-01-03 14:57:44 -05:00

epoll is fashionable.

Added the configuration option --enable-epoll. Use epoll instead of select.
This commit is contained in:
Witold Filipczyk 2006-12-31 19:05:43 +01:00 committed by Witold Filipczyk
parent 38b09e44c7
commit 87e10dd412
4 changed files with 148 additions and 0 deletions

View File

@ -194,6 +194,7 @@ AC_CHECK_HEADERS(stdint.h inttypes.h)
AC_CHECK_HEADERS(locale.h pwd.h) AC_CHECK_HEADERS(locale.h pwd.h)
AC_CHECK_HEADERS(termios.h) AC_CHECK_HEADERS(termios.h)
AC_CHECK_HEADERS(sys/epoll.h, [HAVE_SYS_EPOLL_H=yes])
AC_CHECK_HEADERS(sys/un.h, AC_CHECK_HEADERS(sys/un.h,
[CONFIG_INTERLINK=yes [CONFIG_INTERLINK=yes
@ -297,6 +298,7 @@ AC_HAVE_FUNCS(cygwin_conv_to_full_win32_path)
AC_CHECK_FUNCS(setenv putenv, HAVE_SETENV_OR_PUTENV=yes) AC_CHECK_FUNCS(setenv putenv, HAVE_SETENV_OR_PUTENV=yes)
AC_CHECK_FUNCS(getuid, HAVE_GETUID=yes) AC_CHECK_FUNCS(getuid, HAVE_GETUID=yes)
AC_CHECK_FUNCS(geteuid, HAVE_GETEUID=yes) AC_CHECK_FUNCS(geteuid, HAVE_GETEUID=yes)
AC_CHECK_FUNCS(epoll_ctl, HAVE_EPOLL_CTL=yes)
dnl These aren't probably needed now, as they are commented in links.h. dnl These aren't probably needed now, as they are commented in links.h.
dnl I've no idea about their historical background, but I keep them here dnl I've no idea about their historical background, but I keep them here
@ -1344,6 +1346,9 @@ EL_ARG_ENABLE(CONFIG_SMALL, small, [Small binary],
EL_ARG_ENABLE(CONFIG_UTF8, utf-8, [UTF-8], EL_ARG_ENABLE(CONFIG_UTF8, utf-8, [UTF-8],
[ --enable-utf-8 enable UTF-8 support]) [ --enable-utf-8 enable UTF-8 support])
EL_ARG_DEPEND(CONFIG_EPOLL, epoll, [HAVE_SYS_EPOLL_H:yes HAVE_EPOLL_CTL:yes], [epoll],
[ --enable-epoll enable epoll])
EL_LOG_CONFIG(FESTIVAL, [festival], []) EL_LOG_CONFIG(FESTIVAL, [festival], [])
EL_LOG_CONFIG(FLITE, [flite], []) EL_LOG_CONFIG(FLITE, [flite], [])

View File

@ -15,6 +15,9 @@
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
#endif #endif
#ifdef HAVE_SYS_EPOLL_H
#include <sys/epoll.h>
#endif
#include "elinks.h" #include "elinks.h"
@ -56,6 +59,7 @@
#include "viewer/text/marks.h" #include "viewer/text/marks.h"
struct program program; struct program program;
int epoll_fd;
static int ac; static int ac;
static unsigned char **av; static unsigned char **av;
@ -114,6 +118,15 @@ init(void)
festival.in = -1; festival.in = -1;
festival.out = -1; festival.out = -1;
#endif #endif
#ifdef CONFIG_EPOLL
epoll_fd = epoll_create(1024);
if (epoll_fd == -1) {
program.retval = RET_EPOLL;
program.terminate = 1;
return;
}
#endif
init_osdep(); init_osdep();
check_cwd(); check_cwd();

View File

@ -10,6 +10,7 @@ enum retval {
RET_PING, /* --remote "ping()" found no running ELinkses */ RET_PING, /* --remote "ping()" found no running ELinkses */
RET_REMOTE, /* --remote failed to connect to a running ELinks */ RET_REMOTE, /* --remote failed to connect to a running ELinks */
RET_COMMAND, /* Used internally for exiting from cmdline commands */ RET_COMMAND, /* Used internally for exiting from cmdline commands */
RET_EPOLL, /* Failed to epoll_create */
}; };
struct program { struct program {
@ -19,6 +20,7 @@ struct program {
}; };
extern struct program program; extern struct program program;
extern int epoll_fd;
void shrink_memory(int); void shrink_memory(int);

View File

@ -26,6 +26,10 @@
#include <sys/select.h> #include <sys/select.h>
#endif #endif
#ifdef HAVE_SYS_EPOLL_H
#include <sys/epoll.h>
#endif
#include "elinks.h" #include "elinks.h"
#include "intl/gettext/libintl.h" #include "intl/gettext/libintl.h"
@ -52,6 +56,9 @@ struct thread {
static struct thread threads[FD_SETSIZE]; static struct thread threads[FD_SETSIZE];
#ifdef CONFIG_EPOLL
static struct epoll_event events[FD_SETSIZE];
#else
static fd_set w_read; static fd_set w_read;
static fd_set w_write; static fd_set w_write;
static fd_set w_error; static fd_set w_error;
@ -60,6 +67,7 @@ static fd_set x_read;
static fd_set x_write; static fd_set x_write;
static fd_set x_error; static fd_set x_error;
#endif
static int w_max; static int w_max;
int int
@ -136,6 +144,125 @@ get_handler(int fd, enum select_handler_type tp)
return NULL; return NULL;
} }
#ifdef CONFIG_EPOLL
void
set_handlers(int fd, select_handler_T read_func, select_handler_T write_func,
select_handler_T error_func, void *data)
{
threads[fd].read_func = read_func;
threads[fd].write_func = write_func;
threads[fd].error_func = error_func;
threads[fd].data = data;
struct epoll_event ev;
memset(&ev, 0, sizeof(ev));
ev.data.fd = fd;
if (read_func) ev.events |= EPOLLIN;
if (write_func) ev.events |= EPOLLOUT;
if (error_func) ev.events |= EPOLLERR;
if (read_func || write_func || error_func) {
if (epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &ev))
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev);
if (fd > w_max) w_max = fd;
} else {
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, &ev);
if (w_max == fd) w_max--;
}
}
void
select_loop(void (*init)(void))
{
timeval_T last_time;
int select_errors = 0;
clear_signal_mask_and_handlers();
timeval_now(&last_time);
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);
#endif
init();
check_bottom_halves();
while (!program.terminate) {
int n, i, has_timer, timeout;
timeval_T t;
check_signals();
check_timers(&last_time);
redraw_all_terminals();
if (program.terminate) break;
has_timer = get_next_timer_time(&t);
if (!has_timer) break;
critical_section = 1;
if (check_signals()) {
critical_section = 0;
continue;
}
if (has_timer) {
/* Be sure timeout is not negative. */
timeval_limit_to_zero_or_one(&t);
timeout = (int)timeval_to_milliseconds(&t);
} else {
timeout = -1;
}
n = epoll_wait(epoll_fd, events, w_max, timeout);
if (n < 0) {
/* The following calls (especially gettext)
* might change errno. */
const int errno_from_select = errno;
critical_section = 0;
uninstall_alarm();
if (errno_from_select != EINTR) {
ERROR(gettext("The call to %s failed: %d (%s)"),
"epoll_wait()", errno_from_select, (unsigned char *) strerror(errno_from_select));
if (++select_errors > 10) /* Infinite loop prevention. */
INTERNAL(gettext("%d epoll_wait() failures."),
select_errors);
}
continue;
}
select_errors = 0;
critical_section = 0;
uninstall_alarm();
check_signals();
/*printf("sel: %d\n", n);*/
check_timers(&last_time);
for (i = 0; i < n; i++) {
int fd = events[i].data.fd;
if ((events[i].events & EPOLLIN)
&& threads[fd].read_func) {
threads[fd].read_func(threads[fd].data);
check_bottom_halves();
}
if ((events[i].events & EPOLLOUT)
&& threads[fd].write_func) {
threads[fd].write_func(threads[fd].data);
check_bottom_halves();
}
if ((events[i].events & EPOLLERR)
&& threads[fd].error_func) {
threads[fd].error_func(threads[fd].data);
check_bottom_halves();
}
}
}
close(epoll_fd);
}
#else
void void
set_handlers(int fd, select_handler_T read_func, select_handler_T write_func, set_handlers(int fd, select_handler_T read_func, select_handler_T write_func,
select_handler_T error_func, void *data) select_handler_T error_func, void *data)
@ -312,6 +439,7 @@ select_loop(void (*init)(void))
} }
} }
} }
#endif /* CONFIG_EPOLL */
static int static int
can_read_or_write(int fd, int write) can_read_or_write(int fd, int write)