mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
epoll is fashionable.
Added the configuration option --enable-epoll. Use epoll instead of select.
This commit is contained in:
parent
38b09e44c7
commit
87e10dd412
@ -194,6 +194,7 @@ AC_CHECK_HEADERS(stdint.h inttypes.h)
|
||||
AC_CHECK_HEADERS(locale.h pwd.h)
|
||||
AC_CHECK_HEADERS(termios.h)
|
||||
|
||||
AC_CHECK_HEADERS(sys/epoll.h, [HAVE_SYS_EPOLL_H=yes])
|
||||
|
||||
AC_CHECK_HEADERS(sys/un.h,
|
||||
[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(getuid, HAVE_GETUID=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 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],
|
||||
[ --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(FLITE, [flite], [])
|
||||
|
||||
|
@ -15,6 +15,9 @@
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_EPOLL_H
|
||||
#include <sys/epoll.h>
|
||||
#endif
|
||||
|
||||
#include "elinks.h"
|
||||
|
||||
@ -56,6 +59,7 @@
|
||||
#include "viewer/text/marks.h"
|
||||
|
||||
struct program program;
|
||||
int epoll_fd;
|
||||
|
||||
static int ac;
|
||||
static unsigned char **av;
|
||||
@ -114,6 +118,15 @@ init(void)
|
||||
festival.in = -1;
|
||||
festival.out = -1;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_EPOLL
|
||||
epoll_fd = epoll_create(1024);
|
||||
if (epoll_fd == -1) {
|
||||
program.retval = RET_EPOLL;
|
||||
program.terminate = 1;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
init_osdep();
|
||||
check_cwd();
|
||||
|
||||
|
@ -10,6 +10,7 @@ enum retval {
|
||||
RET_PING, /* --remote "ping()" found no running ELinkses */
|
||||
RET_REMOTE, /* --remote failed to connect to a running ELinks */
|
||||
RET_COMMAND, /* Used internally for exiting from cmdline commands */
|
||||
RET_EPOLL, /* Failed to epoll_create */
|
||||
};
|
||||
|
||||
struct program {
|
||||
@ -19,6 +20,7 @@ struct program {
|
||||
};
|
||||
|
||||
extern struct program program;
|
||||
extern int epoll_fd;
|
||||
|
||||
void shrink_memory(int);
|
||||
|
||||
|
@ -26,6 +26,10 @@
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_EPOLL_H
|
||||
#include <sys/epoll.h>
|
||||
#endif
|
||||
|
||||
#include "elinks.h"
|
||||
|
||||
#include "intl/gettext/libintl.h"
|
||||
@ -52,6 +56,9 @@ struct thread {
|
||||
|
||||
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_write;
|
||||
static fd_set w_error;
|
||||
@ -60,6 +67,7 @@ static fd_set x_read;
|
||||
static fd_set x_write;
|
||||
static fd_set x_error;
|
||||
|
||||
#endif
|
||||
static int w_max;
|
||||
|
||||
int
|
||||
@ -136,6 +144,125 @@ get_handler(int fd, enum select_handler_type tp)
|
||||
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
|
||||
set_handlers(int fd, select_handler_T read_func, select_handler_T write_func,
|
||||
select_handler_T error_func, void *data)
|
||||
@ -312,6 +439,7 @@ select_loop(void (*init)(void))
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_EPOLL */
|
||||
|
||||
static int
|
||||
can_read_or_write(int fd, int write)
|
||||
|
Loading…
Reference in New Issue
Block a user