Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F3152818
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/configure.ac b/configure.ac
index f938447..692cdcc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,353 +1,354 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.61])
AC_INIT([libqb], [0.1.0], [quarterback-devel@fedorahosted.org])
AC_CONFIG_SRCDIR([lib/ringbuffer.c])
AC_CONFIG_HEADERS([include/config.h])
AM_INIT_AUTOMAKE([-Wno-portability])
LT_PREREQ([2.2.6])
LT_INIT
AC_CONFIG_MACRO_DIR([m4])
AC_CANONICAL_HOST
AC_PROG_LIBTOOL
AC_LANG([C])
dnl Fix default variables - "prefix" variable if not specified
if test "$prefix" = "NONE"; then
prefix="/usr"
if test "$localstatedir" = "\${prefix}/var"; then
localstatedir="/var"
fi
if test "$sysconfdir" = "\${prefix}/etc"; then
sysconfdir="/etc"
fi
if test "$libdir" = "\${exec_prefix}/lib"; then
if test -e /usr/lib64; then
libdir="/usr/lib64"
else
libdir="/usr/lib"
fi
fi
fi
if test "$srcdir" = "."; then
AC_MSG_NOTICE([building in place srcdir:$srcdir])
AC_DEFINE([BUILDING_IN_PLACE], 1, [building in place])
else
AC_MSG_NOTICE([building out of tree srcdir:$srcdir])
fi
# Checks for programs.
# check stolen from gnulib/m4/gnu-make.m4
if ! ${MAKE-make} --version /cannot/make/this >/dev/null 2>&1; then
AC_MSG_ERROR([you don't seem to have GNU make; it is required])
fi
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CXX
AC_PROG_AWK
AC_PROG_LN_S
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_CHECK_PROGS([PKGCONFIG], [pkg-config])
AC_CHECK_PROGS([DOXYGEN], [doxygen])
AM_CONDITIONAL(HAVE_DOXYGEN, test -n "${DOXYGEN}")
## local helper functions
# this function checks if CC support options passed as
# args. Global CFLAGS are ignored during this test.
cc_supports_flag() {
local CFLAGS="$@"
AC_MSG_CHECKING([whether $CC supports "$@"])
AC_COMPILE_IFELSE([int main(){return 0;}] ,
[RC=0; AC_MSG_RESULT([yes])],
[RC=1; AC_MSG_RESULT([no])])
return $RC
}
## cleanup
AC_MSG_NOTICE(Sanitizing prefix: ${prefix})
case $prefix in
NONE) prefix=/usr/local;;
esac
AC_MSG_NOTICE(Sanitizing exec_prefix: ${exec_prefix})
case $exec_prefix in
NONE) exec_prefix=$prefix;;
prefix) exec_prefix=$prefix;;
esac
# Checks for libraries.
AC_CHECK_LIB([rt], [mq_open])
AC_CHECK_LIB([dl], [dlopen])
AC_CHECK_LIB([pthread], [pthread_create])
AC_CHECK_LIB([socket], [socket])
PKG_CHECK_MODULES([CHECK], [check >= 0.9.4],[with_check=yes],[with_check=no])
AM_CONDITIONAL(HAVE_CHECK, test "${with_check}" = "yes")
# Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h netinet/in.h stdint.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/sockio.h sys/un.h syslog.h errno.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
AC_C_INLINE
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_INT8_T
AC_TYPE_MODE_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
# Checks for library functions.
AC_FUNC_CHOWN
AC_FUNC_ERROR_AT_LINE
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_FUNC_MMAP
AC_FUNC_REALLOC
AC_FUNC_STRERROR_R
-AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday memset munmap socket strchr strerror strstr])
+AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday memset munmap \
+ socket strchr strerror strstr epoll_create epoll_create1])
## local defines
PACKAGE_FEATURES=""
LINT_FLAGS="-weak -unrecog +posixlib +ignoresigns -fcnuse \
-badflag -D__gnuc_va_list=va_list -D__attribute\(x\)="
# libraries SONAME
SOMAJOR="0"
SOMINOR="1"
SOMICRO="0"
SONAME="${SOMAJOR}.${SOMINOR}.${SOMICRO}"
# local options
AC_ARG_ENABLE([ansi],
[ --enable-ansi : force to build with ANSI standards. ],
[ default="no" ])
AC_ARG_ENABLE([fatal-warnings],
[ --enable-fatal-warnings : enable fatal warnings. ],
[ default="no" ])
AC_ARG_ENABLE([debug],
[ --enable-debug : enable debug build. ],
[ default="no" ])
AC_ARG_ENABLE([coverage],
[ --enable-coverage : coverage analysis of the codebase. ],
[ default="no" ])
AC_ARG_WITH([socket-dir],
[ --with-socket-dir=DIR : socket dir. ],
[ SOCKETDIR="$withval" ],
[ SOCKETDIR="$localstatedir/run" ])
# OS detection
# THIS SECTION MUST DIE!
CP=cp
case "$host_os" in
*linux*)
AC_DEFINE_UNQUOTED([QB_LINUX], [1],
[Compiling for Linux platform])
;;
darwin*)
AC_DEFINE_UNQUOTED([QB_DARWIN], [1],
[Compiling for Darwin platform])
CP=rsync
AC_DEFINE_UNQUOTED([MAP_ANONYMOUS], [MAP_ANON],
[Shared memory define for Darwin platform])
AC_DEFINE_UNQUOTED([PATH_MAX], [4096],
[Number of chars in a path name including nul])
AC_DEFINE_UNQUOTED([NAME_MAX], [255],
[Number of chars in a file name])
;;
*bsd*)
AC_DEFINE_UNQUOTED([QB_BSD], [1],
[Compiling for BSD platform])
AC_DEFINE_UNQUOTED([MAP_ANONYMOUS], [MAP_ANON],
[Shared memory define for Darwin platform])
case "$host_os" in
*freebsd[[234567]]*)
;;
*freebsd*)
AC_DEFINE_UNQUOTED([QB_FREEBSD_GE_8], [1],
[Compiling for FreeBSD >= 8 platform])
;;
esac
;;
*solaris*)
AC_DEFINE_UNQUOTED([QB_SOLARIS], [1],
[Compiling for Solaris platform])
AC_DEFINE_UNQUOTED([TS_CLASS], [1],
[Prevent being scheduled RR])
AC_DEFINE_UNQUOTED([_SEM_SEMUN_UNDEFINED], [1],
[The semun structure is undefined])
CP=rsync
;;
*)
AC_MSG_ERROR([Unsupported OS? hmmmm])
;;
esac
AC_SUBST(CP)
# *FLAGS handling goes here
ENV_CFLAGS="$CFLAGS"
ENV_CPPFLAGS="$CPPFLAGS"
ENV_LDFLAGS="$LDFLAGS"
# debug build stuff
if test "x${enable_debug}" = xyes; then
AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
OPT_CFLAGS="-O0"
PACKAGE_FEATURES="$PACKAGE_FEATURES debug"
else
OPT_CFLAGS="-O3"
fi
# gdb flags
if test "x${GCC}" = xyes; then
GDB_FLAGS="-ggdb3"
else
GDB_FLAGS="-g"
fi
# extra warnings
EXTRA_WARNINGS=""
WARNLIST="
all
shadow
missing-prototypes
missing-declarations
strict-prototypes
declaration-after-statement
pointer-arith
write-strings
cast-align
bad-function-cast
missing-format-attribute
format=2
format-security
format-nonliteral
no-long-long
unsigned-char
gnu89-inline
no-strict-aliasing
"
for j in $WARNLIST; do
if cc_supports_flag -W$j; then
EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j";
fi
done
if test "x${enable_coverage}" = xyes && \
cc_supports_flag -ftest-coverage && \
cc_supports_flag -fprofile-arcs ; then
AC_MSG_NOTICE([Enabling Coverage (enable -O0 by default)])
OPT_CFLAGS="-O0"
COVERAGE_CFLAGS="-ftest-coverage -fprofile-arcs"
COVERAGE_LDFLAGS="-ftest-coverage -fprofile-arcs"
PACKAGE_FEATURES="$PACKAGE_FEATURES coverage"
else
COVERAGE_CFLAGS=""
COVERAGE_LDFLAGS=""
fi
if test "x${enable_ansi}" = xyes && \
cc_supports_flag -std=iso9899:199409 ; then
AC_MSG_NOTICE([Enabling ANSI Compatibility])
ANSI_CPPFLAGS="-ansi -D_GNU_SOURCE -DANSI_ONLY"
PACKAGE_FEATURES="$PACKAGE_FEATURES ansi"
else
ANSI_CPPFLAGS=""
fi
if test "x${enable_fatal_warnings}" = xyes && \
cc_supports_flag -Werror ; then
AC_MSG_NOTICE([Enabling Fatal Warnings (-Werror)])
WERROR_CFLAGS="-Werror"
PACKAGE_FEATURES="$PACKAGE_FEATURES fatal-warnings"
else
WERROR_CFLAGS=""
fi
# final build of *FLAGS
CFLAGS="$ENV_CFLAGS $OPT_CFLAGS $GDB_FLAGS \
$COVERAGE_CFLAGS $EXTRA_WARNINGS $WERROR_CFLAGS"
CPPFLAGS="$ENV_CPPFLAGS $ANSI_CPPFLAGS"
LDFLAGS="$ENV_LDFLAGS $COVERAGE_LDFLAGS"
# substitute what we need:
AC_SUBST([SOCKETDIR])
AC_SUBST([SOMAJOR])
AC_SUBST([SOMINOR])
AC_SUBST([SOMICRO])
AC_SUBST([SONAME])
AC_SUBST([LINT_FLAGS])
AC_DEFINE_UNQUOTED([SOCKETDIR], "$(eval echo ${SOCKETDIR})", [Socket directory])
AC_DEFINE_UNQUOTED([LOCALSTATEDIR], "$(eval echo ${localstatedir})", [localstate directory])
AC_DEFINE_UNQUOTED([PACKAGE_FEATURES], "${PACKAGE_FEATURES}", [quarterback built-in features])
AC_CONFIG_FILES([Makefile
include/Makefile
include/qb/Makefile
lib/Makefile
lib/libqb.pc
tests/Makefile
docs/Makefile
docs/man.dox
docs/html.dox])
AC_OUTPUT
AC_MSG_RESULT([])
AC_MSG_RESULT([$PACKAGE configuration:])
AC_MSG_RESULT([ Version = ${VERSION}])
AC_MSG_RESULT([ Prefix = ${prefix}])
AC_MSG_RESULT([ Executables = ${sbindir}])
AC_MSG_RESULT([ Man pages = ${mandir}])
AC_MSG_RESULT([ Doc dir = ${docdir}])
AC_MSG_RESULT([ Libraries = ${libdir}])
AC_MSG_RESULT([ Header files = ${includedir}])
AC_MSG_RESULT([ Arch-independent files = ${datadir}])
AC_MSG_RESULT([ State information = ${localstatedir}])
AC_MSG_RESULT([ System configuration = ${sysconfdir}])
AC_MSG_RESULT([ SOCKETDIR = ${SOCKETDIR}])
AC_MSG_RESULT([ Features =${PACKAGE_FEATURES}])
AC_MSG_RESULT([])
AC_MSG_RESULT([$PACKAGE build info:])
AC_MSG_RESULT([ Library SONAME = ${SONAME}])
AC_MSG_RESULT([ Default optimization = ${OPT_CFLAGS}])
AC_MSG_RESULT([ Default debug options = ${GDB_CFLAGS}])
AC_MSG_RESULT([ Extra compiler warnings = ${EXTRA_WARNING}])
AC_MSG_RESULT([ Env. defined CFLAG = ${ENV_CFLAGS}])
AC_MSG_RESULT([ Env. defined CPPFLAGS = ${ENV_CPPFLAGS}])
AC_MSG_RESULT([ Env. defined LDFLAGS = ${ENV_LDFLAGS}])
AC_MSG_RESULT([ ANSI defined CPPFLAGS = ${ANSI_CPPFLAGS}])
AC_MSG_RESULT([ Coverage CFLAGS = ${COVERAGE_CFLAGS}])
AC_MSG_RESULT([ Coverage LDFLAGS = ${COVERAGE_LDFLAGS}])
AC_MSG_RESULT([ Fatal War. CFLAGS = ${WERROR_CFLAGS}])
AC_MSG_RESULT([ Final CFLAGS = ${CFLAGS}])
AC_MSG_RESULT([ Final CPPFLAGS = ${CPPFLAGS}])
AC_MSG_RESULT([ Final LDFLAGS = ${LDFLAGS}])
diff --git a/lib/loop_poll.c b/lib/loop_poll.c
index 63b2afc..c2743a0 100644
--- a/lib/loop_poll.c
+++ b/lib/loop_poll.c
@@ -1,298 +1,431 @@
/*
* Copyright (C) 2010 Red Hat, Inc.
*
* Author: Angus Salkeld <asalkeld@redhat.com>
*
* This file is part of libqb.
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
+
+#ifdef HAVE_EPOLL_CREATE1
+#include <sys/epoll.h>
+#define HAVE_EPOLL 1
+#endif /* HAVE_EPOLL_CREATE */
#include <sys/poll.h>
#include <sys/resource.h>
#include <qb/qbdefs.h>
#include <qb/qblist.h>
#include <qb/qbloop.h>
#include "loop_int.h"
+#include "util_int.h"
+
/* logs, std(in|out|err), pipe */
#define POLL_FDS_USED_MISC 50
struct qb_poll_entry {
struct qb_loop_item item;
struct pollfd ufd;
qb_loop_poll_dispatch_fn dispatch_fn;
enum qb_loop_priority p;
int32_t install_pos;
};
struct qb_poll_source {
struct qb_loop_source s;
+#ifdef HAVE_EPOLL
+ struct epoll_event *events;
+#else
struct pollfd *ufds;
+#endif /* HAVE_EPOLL */
int32_t poll_entry_count;
struct qb_poll_entry *poll_entries;
qb_loop_poll_low_fds_event_fn low_fds_event_fn;
int32_t not_enough_fds;
+#ifdef HAVE_EPOLL
+ int32_t epollfd;
+#endif /* HAVE_EPOLL */
};
static struct qb_poll_source * my_src;
+
+#ifdef HAVE_EPOLL
+static int32_t poll_to_epoll_event(int32_t event)
+{
+ int32_t out = 0;
+ if (event & POLLIN) out |= EPOLLIN;
+ if (event & POLLOUT) out |= EPOLLOUT;
+ if (event & POLLPRI) out |= EPOLLPRI;
+ if (event & POLLERR) out |= EPOLLERR;
+ if (event & POLLHUP) out |= EPOLLHUP;
+ if (event & POLLNVAL) out |= EPOLLERR;
+ return out;
+}
+
+static int32_t epoll_to_poll_event(int32_t event)
+{
+ int32_t out = 0;
+ if (event & EPOLLIN) out |= POLLIN;
+ if (event & EPOLLOUT) out |= POLLOUT;
+ if (event & EPOLLPRI) out |= POLLPRI;
+ if (event & EPOLLERR) out |= POLLERR;
+ if (event & EPOLLHUP) out |= POLLHUP;
+ return out;
+}
+#endif /* HAVE_EPOLL */
+
static void poll_dispatch_and_take_back(struct qb_loop_item * item,
enum qb_loop_priority p)
{
struct qb_poll_entry *pe = (struct qb_poll_entry *)item;
int32_t res;
int32_t idx = pe->install_pos;
res = pe->dispatch_fn(pe->ufd.fd, pe->ufd.revents, pe->item.user_data);
pe = &my_src->poll_entries[idx];
if (res < 0) {
pe->ufd.fd = -1; /* empty entry */
}
pe->ufd.revents = 0;
}
static void poll_fds_usage_check(struct qb_poll_source *s)
{
struct rlimit lim;
static int32_t socks_limit = 0;
int32_t send_event = 0;
int32_t socks_used = 0;
int32_t socks_avail = 0;
int32_t i;
if (socks_limit == 0) {
if (getrlimit(RLIMIT_NOFILE, &lim) == -1) {
char error_str[100];
strerror_r(errno, error_str, 100);
printf("getrlimit: %s\n", error_str);
return;
}
socks_limit = lim.rlim_cur;
socks_limit -= POLL_FDS_USED_MISC;
if (socks_limit < 0) {
socks_limit = 0;
}
}
for (i = 0; i < s->poll_entry_count; i++) {
if (s->poll_entries[i].ufd.fd != -1) {
socks_used++;
}
}
socks_avail = socks_limit - socks_used;
if (socks_avail < 0) {
socks_avail = 0;
}
send_event = 0;
if (s->not_enough_fds) {
if (socks_avail > 2) {
s->not_enough_fds = 0;
send_event = 1;
}
} else {
if (socks_avail <= 1) {
s->not_enough_fds = 1;
send_event = 1;
}
}
if (send_event && s->low_fds_event_fn) {
s->low_fds_event_fn(s->not_enough_fds,
socks_avail);
}
}
+#ifdef HAVE_EPOLL
+#define MAX_EVENTS 100
+static int32_t poll_and_add_to_jobs(struct qb_loop_source* src, int32_t ms_timeout)
+{
+ int32_t i;
+ int32_t res;
+ int32_t new_jobs = 0;
+ struct qb_poll_entry * pe;
+ struct qb_poll_source * s = (struct qb_poll_source *)src;
+ struct epoll_event events[MAX_EVENTS];
+
+ poll_fds_usage_check(s);
+
+ retry_poll:
+
+ res = epoll_wait(s->epollfd, events, MAX_EVENTS, ms_timeout);
+
+ if (errno == EINTR && res == -1) {
+ goto retry_poll;
+ } else if (res == -1) {
+ return -errno;
+ }
+
+ for (i = 0; i < res; i++) {
+ pe = &s->poll_entries[events[i].data.u32];
+ if (pe->ufd.fd == -1) {
+ // empty
+ continue;
+ }
+ if (events[i].events == pe->ufd.revents) {
+ // entry already in the job queue.
+ continue;
+ }
+ pe->ufd.revents = epoll_to_poll_event(events[i].events);
+ qb_list_init(&pe->item.list);
+ qb_list_add_tail(&pe->item.list, &s->s.l->level[pe->p].job_head);
+ new_jobs++;
+ }
+
+ return new_jobs;
+}
+#else
static int32_t poll_and_add_to_jobs(struct qb_loop_source* src, int32_t ms_timeout)
{
int32_t i;
int32_t res;
int32_t new_jobs = 0;
struct qb_poll_entry * pe;
struct qb_poll_source * s = (struct qb_poll_source *)src;
poll_fds_usage_check(s);
for (i = 0; i < s->poll_entry_count; i++) {
memcpy(&s->ufds[i], &s->poll_entries[i].ufd, sizeof(struct pollfd));
}
retry_poll:
res = poll(s->ufds, s->poll_entry_count, ms_timeout);
if (errno == EINTR && res == -1) {
goto retry_poll;
} else if (res == -1) {
return -errno;
}
for (i = 0; i < s->poll_entry_count; i++) {
if (s->ufds[i].fd == -1 || s->ufds[i].revents == 0) {
// empty
continue;
}
pe = &s->poll_entries[i];
if (s->ufds[i].revents == pe->ufd.revents) {
// entry already in the job queue.
continue;
}
pe->ufd.revents = s->ufds[i].revents;
qb_list_init(&pe->item.list);
qb_list_add_tail(&pe->item.list, &s->s.l->level[pe->p].job_head);
new_jobs++;
}
return new_jobs;
}
-
+#endif /* HAVE_EPOLL */
struct qb_loop_source*
qb_loop_poll_init(struct qb_loop *l)
{
my_src = malloc(sizeof(struct qb_poll_source));
my_src->s.l = l;
my_src->s.dispatch_and_take_back = poll_dispatch_and_take_back;
my_src->s.poll = poll_and_add_to_jobs;
my_src->poll_entries = 0;
- my_src->ufds = 0;
my_src->poll_entry_count = 0;
my_src->low_fds_event_fn = NULL;
my_src->not_enough_fds = 0;
+#ifdef HAVE_EPOLL
+ my_src->epollfd = epoll_create1(EPOLL_CLOEXEC);
+ my_src->events = 0;
+#else
+ my_src->ufds = 0;
+#endif /* HAVE_EPOLL */
+
qb_list_init(&my_src->s.list);
qb_list_add_tail(&my_src->s.list, &l->source_head);
return (struct qb_loop_source*)my_src;
}
int32_t qb_loop_poll_low_fds_event_set(
qb_loop_t *l,
qb_loop_poll_low_fds_event_fn fn)
{
my_src->low_fds_event_fn = fn;
return 0;
}
int32_t qb_loop_poll_add(struct qb_loop *l,
enum qb_loop_priority p,
int32_t fd,
int32_t events,
void *data,
qb_loop_poll_dispatch_fn dispatch_fn)
{
struct qb_poll_entry *poll_entries;
struct qb_poll_entry *pe;
- struct pollfd *ufds;
int32_t found = 0;
int32_t install_pos;
int32_t res = 0;
int32_t new_size = 0;
+#ifdef HAVE_EPOLL
+ struct epoll_event *ev;
+#else
+ struct pollfd *ufds;
+#endif /* HAVE_EPOLL */
for (found = 0, install_pos = 0;
install_pos < my_src->poll_entry_count; install_pos++) {
if (my_src->poll_entries[install_pos].ufd.fd == -1) {
found = 1;
break;
}
}
if (found == 0) {
/*
* Grow pollfd list
*/
new_size = (my_src->poll_entry_count + 1) * sizeof(struct qb_poll_entry);
poll_entries = realloc(my_src->poll_entries, new_size);
if (poll_entries == NULL) {
return -ENOMEM;
}
my_src->poll_entries = poll_entries;
+#ifdef HAVE_EPOLL
+ new_size = (my_src->poll_entry_count+ 1) * sizeof(struct epoll_event);
+ ev = realloc(my_src->events, new_size);
+ if (ev == NULL) {
+ return -ENOMEM;
+ }
+ my_src->events = ev;
+#else
new_size = (my_src->poll_entry_count+ 1) * sizeof(struct pollfd);
ufds = realloc(my_src->ufds, new_size);
if (ufds == NULL) {
return -ENOMEM;
}
my_src->ufds = ufds;
+#endif /* HAVE_EPOLL */
my_src->poll_entry_count += 1;
install_pos = my_src->poll_entry_count - 1;
}
/*
* Install new dispatch handler
*/
pe = &my_src->poll_entries[install_pos];
pe->install_pos = install_pos;
pe->ufd.fd = fd;
pe->ufd.events = events;
pe->ufd.revents = 0;
pe->dispatch_fn = dispatch_fn;
pe->item.user_data = data;
pe->item.source = (struct qb_loop_source*)my_src;
pe->p = p;
+#ifdef HAVE_EPOLL
+ ev = &my_src->events[install_pos];
+ ev->events = poll_to_epoll_event(events);
+ ev->data.u32 = install_pos;
+ if (epoll_ctl(my_src->epollfd, EPOLL_CTL_ADD, fd, ev) == -1) {
+ res = -errno;
+ qb_util_log(LOG_ERR, "epoll_ctl(add) : %s", strerror(-res));
+ }
+#endif /* HAVE_EPOLL */
return (res);
}
int32_t qb_loop_poll_mod(struct qb_loop *l,
enum qb_loop_priority p,
int32_t fd,
int32_t events,
qb_loop_poll_dispatch_fn dispatch_fn)
{
int32_t i;
+ int32_t res = 0;
struct qb_poll_entry *pe;
/*
* Find file descriptor to modify events and dispatch function
*/
for (i = 0; i < my_src->poll_entry_count; i++) {
pe = &my_src->poll_entries[i];
- if (pe->ufd.fd == fd) {
+ if (pe->ufd.fd != fd) {
+ continue;
+ }
+ pe->dispatch_fn = dispatch_fn;
+ pe->item.user_data = data;
+ pe->p = p;
+ if (pe->ufd.events != events) {
+#ifdef HAVE_EPOLL
+ my_src->events[i].events = poll_to_epoll_event(events);
+ my_src->events[i].data.u32 = i;
+ if (epoll_ctl(my_src->epollfd, EPOLL_CTL_MOD, fd, &my_src->events[i]) == -1) {
+ res = -errno;
+ qb_util_log(LOG_ERR, "epoll_ctl(mod) : %s", strerror(-res));
+ }
+#endif /* HAVE_EPOLL */
pe->ufd.events = events;
- pe->dispatch_fn = dispatch_fn;
- pe->p = p;
- return 0;
}
+ return res;
}
return -EBADF;
}
int32_t qb_loop_poll_del(struct qb_loop *l, int32_t fd)
{
int32_t i;
+ int32_t res = 0;
struct qb_poll_entry *pe;
/*
* Find file descriptor to modify events and dispatch function
*/
for (i = 0; i < my_src->poll_entry_count; i++) {
pe = &my_src->poll_entries[i];
- if (pe->ufd.fd == fd) {
- my_src->ufds[i].fd = -1;
- my_src->ufds[i].events = 0;
- my_src->ufds[i].revents = 0;
- pe->ufd.fd = -1;
- pe->ufd.events = 0;
- pe->ufd.revents = 0;
- return 0;
+ if (pe->ufd.fd != fd) {
+ continue;
+ }
+ pe->ufd.fd = -1;
+ pe->ufd.events = 0;
+ pe->ufd.revents = 0;
+#ifdef HAVE_EPOLL
+ if (epoll_ctl(my_src->epollfd, EPOLL_CTL_DEL, fd, NULL) == -1) {
+ res = -errno;
+ qb_util_log(LOG_ERR, "epoll_ctl(del) : %s",
+ strerror(-res));
}
+#else
+ my_src->ufds[i].fd = -1;
+ my_src->ufds[i].events = 0;
+ my_src->ufds[i].revents = 0;
+#endif /* HAVE_EPOLL */
+ return 0;
}
return -EBADF;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Feb 25, 4:09 AM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1464668
Default Alt Text
(20 KB)
Attached To
Mode
rQ LibQB
Attached
Detach File
Event Timeline
Log In to Comment