mirror of
https://salsa.debian.org/ha-team/libqb
synced 2026-08-10 16:10:48 +00:00
Remove timerfd usage and go back to timelist.
timefd is using too much cpu and it is using up file descriptors. timelist is also more portable and now I have less code to maintain. Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
parent
4356fbf577
commit
002f009941
9
check
9
check
@ -14,7 +14,6 @@ help_all() {
|
||||
echo " nosection Check without gcc __attribute__(section)"
|
||||
echo " noepoll Check using poll (not epoll)"
|
||||
echo " nogettime Check without gettime()"
|
||||
echo " notimerfd Check without timerfd"
|
||||
echo " bsd Check with a bsd-like config"
|
||||
echo " mac Check with a mac/darwin-like config"
|
||||
echo " dist do make distcheck"
|
||||
@ -96,11 +95,6 @@ check_sysv() {
|
||||
export CFLAGS=$ORIG_CFLAGS
|
||||
}
|
||||
|
||||
check_notimerfd() {
|
||||
# no timerfd
|
||||
check "ac_cv_func_timerfd_create=no ac_cv_header_sys_timerfd_h=no"
|
||||
}
|
||||
|
||||
check_nogettime() {
|
||||
# no clock_gettime
|
||||
check "ac_cv_func_clock_gettime=no"
|
||||
@ -286,9 +280,6 @@ case $command in
|
||||
dist)
|
||||
check_dist
|
||||
;;
|
||||
notimerfd)
|
||||
check_notimerfd
|
||||
;;
|
||||
coverity)
|
||||
check_coverity
|
||||
;;
|
||||
|
||||
@ -118,7 +118,7 @@ AC_HEADER_SYS_WAIT
|
||||
|
||||
AC_CHECK_HEADERS([arpa/inet.h link.h fcntl.h inttypes.h limits.h netinet/in.h stdint.h \
|
||||
dlfcn.h time.h sys/time.h stdlib.h string.h strings.h sys/types.h sys/stat.h \
|
||||
sys/param.h sys/socket.h sys/time.h sys/timerfd.h sys/poll.h sys/epoll.h sys/uio.h \
|
||||
sys/param.h sys/socket.h sys/time.h sys/poll.h sys/epoll.h sys/uio.h \
|
||||
sys/sockio.h sys/un.h sys/resource.h syslog.h errno.h unistd.h sys/mman.h \
|
||||
sys/sem.h sys/ipc.h sys/msg.h mqueue.h])
|
||||
|
||||
@ -143,7 +143,7 @@ AC_FUNC_MMAP
|
||||
AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday localtime localtime_r \
|
||||
memset munmap socket strchr strrchr strdup strerror strstr \
|
||||
poll epoll_create epoll_create1 random rand getrlimit sysconf \
|
||||
pthread_spin_lock timerfd_create pthread_setschedparam \
|
||||
pthread_spin_lock pthread_setschedparam \
|
||||
sched_get_priority_max sched_setscheduler])
|
||||
|
||||
AC_CONFIG_LIBOBJ_DIR(lib)
|
||||
@ -435,9 +435,6 @@ if test "x${supports_posix_mq}" = xyes ; then
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_POSIX_MQ, [test "x${supports_posix_mq}" = xyes])
|
||||
|
||||
|
||||
AM_CONDITIONAL(USE_TIMERFD, [test "x$ac_cv_func_timerfd_create" = xyes])
|
||||
|
||||
# --- callsite sections ---
|
||||
if test "x${GCC}" = xyes; then
|
||||
AC_MSG_CHECKING([whether GCC supports __attribute__((section())])
|
||||
|
||||
@ -103,10 +103,6 @@
|
||||
#define HAVE_MONOTONIC_CLOCK 1
|
||||
#endif /* have monotonic clock */
|
||||
|
||||
#ifdef HAVE_TIMERFD_CREATE
|
||||
#define HAVE_TIMERFD 1
|
||||
#endif /* HAVE_TIMERFD_CREATE */
|
||||
|
||||
#ifdef HAVE_EPOLL_CREATE1
|
||||
#define HAVE_EPOLL 1
|
||||
#endif /* HAVE_EPOLL_CREATE */
|
||||
|
||||
@ -39,7 +39,7 @@ lib_LTLIBRARIES = libqb.la
|
||||
|
||||
libqb_la_LDFLAGS = -version-info 10:1:10
|
||||
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c array.c \
|
||||
loop.c loop_poll.c loop_job.c \
|
||||
loop.c loop_poll.c loop_job.c loop_timerlist.c \
|
||||
ipcc.c ipcs.c ipc_shm.c ipc_us.c \
|
||||
log.c log_thread.c log_blackbox.c log_file.c \
|
||||
log_syslog.c log_dcs.c log_format.c \
|
||||
@ -56,10 +56,6 @@ if HAVE_POSIX_MQ
|
||||
libqb_la_SOURCES+=ipc_posix_mq.c
|
||||
endif
|
||||
|
||||
if USE_TIMERFD
|
||||
else
|
||||
libqb_la_SOURCES+=loop_timerlist.c
|
||||
endif
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libqb.pc
|
||||
|
||||
|
||||
210
lib/loop_poll.c
210
lib/loop_poll.c
@ -34,9 +34,6 @@ int epoll_create1(int flags);
|
||||
#include <sys/poll.h>
|
||||
#endif /* HAVE_SYS_POLL_H */
|
||||
#ifndef S_SPLINT_S
|
||||
#ifdef HAVE_SYS_TIMERFD_H
|
||||
#include <sys/timerfd.h>
|
||||
#endif /* HAVE_SYS_TIMERFD_H */
|
||||
#endif /* S_SPLINT_S */
|
||||
#include <signal.h>
|
||||
|
||||
@ -142,7 +139,7 @@ _poll_entry_check_generate_(struct qb_poll_entry *pe)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_TIMERFD) || defined(HAVE_EPOLL)
|
||||
#if defined(HAVE_EPOLL)
|
||||
static int32_t
|
||||
_poll_entry_from_handle_(struct qb_poll_source *s,
|
||||
uint64_t handle_in, struct qb_poll_entry **pe_pt)
|
||||
@ -162,7 +159,7 @@ _poll_entry_from_handle_(struct qb_poll_source *s,
|
||||
*pe_pt = pe;
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_TIMERFD or HAVE_EPOLL */
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
static void
|
||||
_poll_entry_mark_deleted_(struct qb_poll_entry *pe)
|
||||
@ -678,209 +675,6 @@ qb_loop_poll_del(struct qb_loop * lp, int32_t fd)
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TIMERFD
|
||||
static int32_t
|
||||
_qb_timer_add_to_jobs_(struct qb_loop *l, struct qb_poll_entry *pe)
|
||||
{
|
||||
uint64_t expired = 0;
|
||||
ssize_t bytes = 0;
|
||||
|
||||
assert(pe->item.type == QB_LOOP_TIMER);
|
||||
if (pe->ufd.revents == POLLIN) {
|
||||
bytes = read(pe->ufd.fd, &expired, sizeof(expired));
|
||||
if (bytes != sizeof(expired)) {
|
||||
qb_util_perror(LOG_WARNING,
|
||||
"couldn't read from timer fd %zd",
|
||||
bytes);
|
||||
}
|
||||
qb_loop_level_item_add(&l->level[pe->p], &pe->item);
|
||||
} else {
|
||||
qb_util_log(LOG_ERR, "timer revents: %d expected %d",
|
||||
pe->ufd.revents, POLLIN);
|
||||
}
|
||||
close(pe->ufd.fd);
|
||||
pe->ufd.fd = -1;
|
||||
pe->state = QB_POLL_ENTRY_JOBLIST;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_loop_timer_msec_duration_to_expire(struct qb_loop_source * timer_source)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct qb_loop_source *
|
||||
qb_loop_timer_create(struct qb_loop *l)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
qb_loop_timer_destroy(struct qb_loop *l)
|
||||
{
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_loop_timer_add(struct qb_loop *lp,
|
||||
enum qb_loop_priority p,
|
||||
uint64_t nsec_duration,
|
||||
void *data,
|
||||
qb_loop_timer_dispatch_fn timer_fn,
|
||||
qb_loop_timer_handle * timer_handle_out)
|
||||
{
|
||||
struct qb_poll_entry *pe;
|
||||
int32_t fd;
|
||||
int32_t res;
|
||||
int32_t size, new_size;
|
||||
struct itimerspec its;
|
||||
struct qb_loop *l = lp;
|
||||
|
||||
if (l == NULL) {
|
||||
l = qb_loop_default_get();
|
||||
}
|
||||
if (l == NULL || timer_fn == NULL) {
|
||||
qb_util_log(LOG_ERR,
|
||||
"can't add a timer with either (l == NULL || timer_fn == NULL)");
|
||||
return -EINVAL;
|
||||
}
|
||||
fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||
if (fd == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "failed to create timer");
|
||||
return res;
|
||||
}
|
||||
|
||||
its.it_interval.tv_sec = 0;
|
||||
its.it_interval.tv_nsec = 0;
|
||||
its.it_value.tv_sec = nsec_duration / QB_TIME_NS_IN_SEC;
|
||||
its.it_value.tv_nsec = nsec_duration % QB_TIME_NS_IN_SEC;
|
||||
|
||||
res = timerfd_settime(fd, 0, &its, NULL);
|
||||
if (res == -1) {
|
||||
res = -errno;
|
||||
qb_util_perror(LOG_ERR, "failed to set time on timer");
|
||||
goto close_and_return;
|
||||
}
|
||||
|
||||
size = ((struct qb_poll_source *)l->fd_source)->poll_entry_count;
|
||||
res = _poll_add_(l, p, fd, POLLIN, data, &pe);
|
||||
if (res != 0) {
|
||||
goto close_and_return;
|
||||
}
|
||||
new_size = ((struct qb_poll_source *)l->fd_source)->poll_entry_count;
|
||||
if (new_size > size) {
|
||||
qb_util_log(LOG_TRACE, "grown poll array to %d for timer %d",
|
||||
new_size, fd);
|
||||
}
|
||||
pe->timer_dispatch_fn = timer_fn;
|
||||
pe->item.type = QB_LOOP_TIMER;
|
||||
pe->add_to_jobs = _qb_timer_add_to_jobs_;
|
||||
|
||||
if (timer_handle_out) {
|
||||
*timer_handle_out = (((uint64_t) (pe->check)) << 32) | pe->install_pos;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
close_and_return:
|
||||
close(fd);
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_loop_timer_del(struct qb_loop * lp, qb_loop_timer_handle th)
|
||||
{
|
||||
struct qb_poll_entry *pe;
|
||||
struct qb_poll_source *s;
|
||||
int32_t res;
|
||||
struct qb_loop *l = lp;
|
||||
|
||||
if (l == NULL) {
|
||||
l = qb_loop_default_get();
|
||||
}
|
||||
if (l == NULL || th == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
s = (struct qb_poll_source *)l->fd_source;
|
||||
res = _poll_entry_from_handle_(s, th, &pe);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (pe->item.type != QB_LOOP_TIMER) {
|
||||
qb_util_log(LOG_WARNING,
|
||||
"trying to delete timer but handle points to type:%d",
|
||||
pe->item.type);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (pe->state == QB_POLL_ENTRY_DELETED) {
|
||||
return 0;
|
||||
}
|
||||
if (pe->state == QB_POLL_ENTRY_JOBLIST) {
|
||||
qb_loop_level_item_del(&l->level[pe->p], &pe->item);
|
||||
qb_util_log(LOG_DEBUG, "deleting timer in JOBLIST");
|
||||
}
|
||||
if (pe->state != QB_POLL_ENTRY_ACTIVE &&
|
||||
pe->state != QB_POLL_ENTRY_JOBLIST) {
|
||||
qb_util_log(LOG_WARNING, "trying to delete timer with state:%d",
|
||||
pe->state);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (pe->ufd.fd != -1) {
|
||||
#ifdef HAVE_EPOLL
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_DEL, pe->ufd.fd, NULL) ==
|
||||
-1) {
|
||||
qb_util_perror(LOG_DEBUG, "epoll_ctl(del:%d)",
|
||||
pe->ufd.fd);
|
||||
}
|
||||
#else
|
||||
s->ufds[pe->install_pos].fd = -1;
|
||||
s->ufds[pe->install_pos].events = 0;
|
||||
s->ufds[pe->install_pos].revents = 0;
|
||||
#endif /* HAVE_EPOLL */
|
||||
close(pe->ufd.fd);
|
||||
}
|
||||
_poll_entry_mark_deleted_(pe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
qb_loop_timer_expire_time_get(struct qb_loop * lp, qb_loop_timer_handle th)
|
||||
{
|
||||
struct qb_poll_entry *pe;
|
||||
struct qb_poll_source *s;
|
||||
int32_t res = 0;
|
||||
struct itimerspec its;
|
||||
struct qb_loop *l = lp;
|
||||
|
||||
if (l == NULL) {
|
||||
l = qb_loop_default_get();
|
||||
}
|
||||
if (l == NULL || th == 0) {
|
||||
return 0;
|
||||
}
|
||||
s = (struct qb_poll_source *)l->fd_source;
|
||||
res = _poll_entry_from_handle_(s, th, &pe);
|
||||
if (res != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (timerfd_gettime(pe->ufd.fd, &its) == -1) {
|
||||
return 0;
|
||||
}
|
||||
return (its.it_value.tv_sec * QB_TIME_NS_IN_SEC) + its.it_value.tv_nsec;
|
||||
}
|
||||
|
||||
#endif /* HAVE_TIMERFD */
|
||||
|
||||
int32_t
|
||||
qb_loop_timer_is_running(qb_loop_t *l, qb_loop_timer_handle th)
|
||||
{
|
||||
return (qb_loop_timer_expire_time_get(l, th) > 0);
|
||||
}
|
||||
|
||||
static int32_t pipe_fds[2] = { -1, -1 };
|
||||
|
||||
struct qb_signal_source {
|
||||
|
||||
@ -277,3 +277,9 @@ qb_loop_timer_expire_time_get(struct qb_loop * lp, qb_loop_timer_handle th)
|
||||
|
||||
return timerlist_expire_time(&s->timerlist, t->timerlist_handle);
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_loop_timer_is_running(qb_loop_t *l, qb_loop_timer_handle th)
|
||||
{
|
||||
return (qb_loop_timer_expire_time_get(l, th) > 0);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user