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:
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(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], [])
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user