diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/afb-export.c | 20 | ||||
-rw-r--r-- | src/afb-fdev.c | 19 | ||||
-rw-r--r-- | src/afb-socket.c | 11 | ||||
-rw-r--r-- | src/evmgr.c | 202 | ||||
-rw-r--r-- | src/evmgr.h | 5 | ||||
-rw-r--r-- | src/fdev-systemd.h | 1 | ||||
-rw-r--r-- | src/jobs.c | 9 | ||||
-rw-r--r-- | src/jobs.h | 3 | ||||
-rw-r--r-- | src/main-afb-daemon.c | 6 | ||||
-rw-r--r-- | src/systemd.c | 3 | ||||
-rw-r--r-- | src/systemd.h | 4 | ||||
-rw-r--r-- | src/watchdog.c | 9 |
13 files changed, 234 insertions, 60 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 71cd1ff2..64a8d973 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,6 +66,8 @@ add_definitions( -DWITH_DBUS_TRANSPARENCY=$<BOOL:${INCLUDE_DBUS_TRANSPARENCY}> -DWITH_SUPERVISION=$<BOOL:${INCLUDE_SUPERVISOR}> -DWITH_DYNAMIC_BINDING=$<BOOL:${WITH_DYNAMIC_BINDING}> + -DWITH_SYSTEMD=$<BOOL:${WITH_SYSTEMD}> + -DWITH_FDEV_EPOLL=$<NOT:$<BOOL:${WITH_SYSTEMD}>> ) ############################################################################ diff --git a/src/afb-export.c b/src/afb-export.c index 8ebe8e06..202a73f6 100644 --- a/src/afb-export.c +++ b/src/afb-export.c @@ -50,7 +50,9 @@ #include "afb-xreq.h" #include "afb-calls.h" +#if WITH_SYSTEMD #include "systemd.h" +#endif #include "jobs.h" #include "verbose.h" #include "globset.h" @@ -312,20 +314,35 @@ static int event_broadcast_cb(struct afb_api_x3 *closure, const char *name, stru static struct sd_event *get_event_loop(struct afb_api_x3 *closure) { +#if WITH_SYSTEMD jobs_acquire_event_manager(); return systemd_get_event_loop(); +#else + errno = ENOTSUP; + return NULL; +#endif } static struct sd_bus *get_user_bus(struct afb_api_x3 *closure) { +#if WITH_SYSTEMD jobs_acquire_event_manager(); return systemd_get_user_bus(); +#else + errno = ENOTSUP; + return NULL; +#endif } static struct sd_bus *get_system_bus(struct afb_api_x3 *closure) { +#if WITH_SYSTEMD jobs_acquire_event_manager(); return systemd_get_system_bus(); +#else + errno = ENOTSUP; + return NULL; +#endif } static int rootdir_open_locale_cb(struct afb_api_x3 *closure, const char *filename, int flags, const char *locale) @@ -481,7 +498,6 @@ static struct sd_event *hooked_get_event_loop(struct afb_api_x3 *closure) struct afb_export *export = from_api_x3(closure); struct sd_event *r; - jobs_acquire_event_manager(); r = get_event_loop(closure); return afb_hook_api_get_event_loop(export, r); } @@ -491,7 +507,6 @@ static struct sd_bus *hooked_get_user_bus(struct afb_api_x3 *closure) struct afb_export *export = from_api_x3(closure); struct sd_bus *r; - jobs_acquire_event_manager(); r = get_user_bus(closure); return afb_hook_api_get_user_bus(export, r); } @@ -501,7 +516,6 @@ static struct sd_bus *hooked_get_system_bus(struct afb_api_x3 *closure) struct afb_export *export = from_api_x3(closure); struct sd_bus *r; - jobs_acquire_event_manager(); r = get_system_bus(closure); return afb_hook_api_get_system_bus(export, r); } diff --git a/src/afb-fdev.c b/src/afb-fdev.c index a5f95660..e98d39d2 100644 --- a/src/afb-fdev.c +++ b/src/afb-fdev.c @@ -15,9 +15,12 @@ * limitations under the License. */ +#include "evmgr.h" #include "fdev.h" - #include "jobs.h" + +#if WITH_SYSTEMD + #include "systemd.h" #include "fdev-systemd.h" @@ -26,3 +29,17 @@ struct fdev *afb_fdev_create(int fd) jobs_acquire_event_manager(); return fdev_systemd_create(systemd_get_event_loop(), fd); } + +#endif +#if WITH_FDEV_EPOLL + +#include "evmgr.h" +#include "fdev-epoll.h" + +struct fdev *afb_fdev_create(int fd) +{ + struct evmgr *evmgr = jobs_acquire_event_manager(); + return fdev_epoll_add(evmgr_get_fdev_epoll(evmgr), fd); +} + +#endif diff --git a/src/afb-socket.c b/src/afb-socket.c index cf788de6..754baea0 100644 --- a/src/afb-socket.c +++ b/src/afb-socket.c @@ -32,10 +32,13 @@ #include "afb-fdev.h" #include "afb-socket.h" -#include "systemd.h" #include "fdev.h" #include "verbose.h" +#if WITH_SYSTEMD +#include "systemd.h" +#endif + #define BACKLOG 5 /******************************************************************************/ @@ -225,11 +228,11 @@ static int open_tcp(const char *spec, int server, int reuseaddr) */ static int open_systemd(const char *spec) { -#if defined(NO_SYSTEMD_ACTIVATION) +#if WITH_SYSTEMD + return systemd_fds_for(spec); +#else errno = EAFNOSUPPORT; return -1; -#else - return systemd_fds_for(spec); #endif } diff --git a/src/evmgr.c b/src/evmgr.c index 2dc35e42..d26502df 100644 --- a/src/evmgr.c +++ b/src/evmgr.c @@ -33,20 +33,92 @@ #include "evmgr.h" #include "verbose.h" + +#if WITH_SYSTEMD #include "systemd.h" +#else +#include "fdev-epoll.h" +#include "fdev.h" +#endif /** Description of handled event loops */ struct evmgr { - unsigned state; /**< encoded state */ int efd; /**< event notification */ + unsigned state; /**< encoded state */ void *holder; /**< holder of the evmgr */ +#if WITH_SYSTEMD struct sd_event *sdev; /**< the systemd event loop */ +#endif +#if WITH_FDEV_EPOLL + struct fdev_epoll *fdev_epoll; + struct fdev *fdev; +#endif }; #define EVLOOP_STATE_WAIT 1U #define EVLOOP_STATE_RUN 2U + +/** + * Internal callback for evmgr management. + * The effect of this function is hidden: it exits + * the waiting poll if any. + */ +static void evmgr_on_efd_event(struct evmgr *evmgr) +{ + uint64_t x; + read(evmgr->efd, &x, sizeof x); +} + +/** + * wakeup the event loop if needed by sending + * an event. + */ +void evmgr_wakeup(struct evmgr *evmgr) +{ + uint64_t x; + + if (evmgr->state & EVLOOP_STATE_WAIT) { + x = 1; + write(evmgr->efd, &x, sizeof x); + } +} + +/** + */ +void *evmgr_holder(struct evmgr *evmgr) +{ + return evmgr->holder; +} + +/** + */ +int evmgr_release_if(struct evmgr *evmgr, void *holder) +{ + if (evmgr->holder != holder) + return 0; + evmgr->holder = 0; + return 1; +} + +/** + */ +int evmgr_try_hold(struct evmgr *evmgr, void *holder) +{ + if (!evmgr->holder) + evmgr->holder = holder; + return evmgr->holder == holder; +} + +/******************************************************************************/ +/******************************************************************************/ +/****** SYSTEM D ******/ +/******************************************************************************/ +/******************************************************************************/ + +#if WITH_SYSTEMD + /** * Run the event loop is set. */ @@ -98,59 +170,101 @@ int evmgr_can_run(struct evmgr *evmgr) /** * Internal callback for evmgr management. * The effect of this function is hidden: it exits - * the waiting poll if any. + * the waiting poll if any. Then it wakes up a thread + * awaiting the evmgr using signal. */ -static void evmgr_on_efd_event(struct evmgr *evmgr) +static int on_evmgr_efd(sd_event_source *s, int fd, uint32_t revents, void *userdata) { - uint64_t x; - read(evmgr->efd, &x, sizeof x); + struct evmgr *evmgr = userdata; + evmgr_on_efd_event(evmgr); + return 1; } /** - * wakeup the event loop if needed by sending - * an event. + * Gets a sd_event item for the current thread. + * @return a sd_event or NULL in case of error */ -void evmgr_wakeup(struct evmgr *evmgr) +int evmgr_create(struct evmgr **result) { - uint64_t x; + int rc; + struct evmgr *evmgr; - if (evmgr->state & EVLOOP_STATE_WAIT) { - x = 1; - write(evmgr->efd, &x, sizeof x); + /* creates the evmgr on need */ + evmgr = malloc(sizeof *evmgr); + if (!evmgr) { + ERROR("out of memory"); + rc = -ENOMEM; + goto error; + } + + /* creates the eventfd for waking up polls */ + evmgr->efd = eventfd(0, EFD_CLOEXEC|EFD_SEMAPHORE); + if (evmgr->efd < 0) { + ERROR("can't make eventfd for events"); + rc = -errno; + goto error1; } + /* create the systemd event loop */ + evmgr->sdev = systemd_get_event_loop(); + if (!evmgr->sdev) { + ERROR("can't make new event loop"); + goto error2; + } + /* put the eventfd in the event loop */ + rc = sd_event_add_io(evmgr->sdev, NULL, evmgr->efd, EPOLLIN, on_evmgr_efd, evmgr); + if (rc < 0) { + ERROR("can't register eventfd"); + goto error2; + } + + /* start the creation */ + evmgr->state = 0; + evmgr->holder = 0; + *result = evmgr; + return 0; + + +error2: + close(evmgr->efd); +error1: + free(evmgr); +error: + *result = 0; + return rc; } +#endif +#if WITH_FDEV_EPOLL + /** + * Run the event loop is set. */ -void *evmgr_holder(struct evmgr *evmgr) +void evmgr_run(struct evmgr *evmgr) { - return evmgr->holder; + int rc; + + evmgr->state = EVLOOP_STATE_WAIT|EVLOOP_STATE_RUN; + rc = fdev_epoll_wait_and_dispatch(evmgr->fdev_epoll, -1); + evmgr->state = 0; } -/** - */ -int evmgr_release_if(struct evmgr *evmgr, void *holder) +void evmgr_job_run(int signum, struct evmgr *evmgr) { - if (evmgr->holder != holder) - return 0; - evmgr->holder = 0; - return 1; + if (signum) + evmgr->state = 0; + else + evmgr_run(evmgr); } -/** - */ -int evmgr_try_hold(struct evmgr *evmgr, void *holder) +int evmgr_can_run(struct evmgr *evmgr) { - if (!evmgr->holder) - evmgr->holder = holder; - return evmgr->holder == holder; + return !evmgr->state; } -/******************************************************************************/ -/******************************************************************************/ -/****** SYSTEM D ******/ -/******************************************************************************/ -/******************************************************************************/ +struct fdev_epoll *evmgr_get_fdev_epoll(struct evmgr *evmgr) +{ + return evmgr->fdev_epoll; +} /** * Internal callback for evmgr management. @@ -158,11 +272,10 @@ int evmgr_try_hold(struct evmgr *evmgr, void *holder) * the waiting poll if any. Then it wakes up a thread * awaiting the evmgr using signal. */ -static int on_evmgr_efd(sd_event_source *s, int fd, uint32_t revents, void *userdata) +static void on_evmgr_efd(void *closure, uint32_t event, struct fdev *fdev) { - struct evmgr *evmgr = userdata; + struct evmgr *evmgr = closure; evmgr_on_efd_event(evmgr); - return 1; } /** @@ -189,19 +302,23 @@ int evmgr_create(struct evmgr **result) rc = -errno; goto error1; } + /* create the systemd event loop */ - evmgr->sdev = systemd_get_event_loop(); - if (!evmgr->sdev) { + evmgr->fdev_epoll = fdev_epoll_create(); + if (!evmgr->fdev_epoll) { ERROR("can't make new event loop"); goto error2; } /* put the eventfd in the event loop */ - rc = sd_event_add_io(evmgr->sdev, NULL, evmgr->efd, EPOLLIN, on_evmgr_efd, evmgr); - if (rc < 0) { - ERROR("can't register eventfd"); - goto error2; + evmgr->fdev = fdev_epoll_add(evmgr->fdev_epoll, evmgr->efd); + if (evmgr->fdev == NULL) { + ERROR("can't add eventfd"); + goto error3; } + fdev_set_callback(evmgr->fdev, on_evmgr_efd, evmgr); + fdev_set_events(evmgr->fdev, EPOLLIN); + /* start the creation */ evmgr->state = 0; evmgr->holder = 0; @@ -209,6 +326,8 @@ int evmgr_create(struct evmgr **result) return 0; +error3: + fdev_epoll_destroy(evmgr->fdev_epoll); error2: close(evmgr->efd); error1: @@ -218,3 +337,4 @@ error: return rc; } +#endif diff --git a/src/evmgr.h b/src/evmgr.h index c78ea33f..e7af226f 100644 --- a/src/evmgr.h +++ b/src/evmgr.h @@ -28,3 +28,8 @@ extern int evmgr_release_if(struct evmgr *evmgr, void *holder); extern int evmgr_try_hold(struct evmgr *evmgr, void *holder); extern void *evmgr_holder(struct evmgr *evmgr); extern int evmgr_create(struct evmgr **result); + +#if WITH_FDEV_EPOLL +struct fdev_epoll; +extern struct fdev_epoll *evmgr_get_fdev_epoll(struct evmgr *evmgr); +#endif diff --git a/src/fdev-systemd.h b/src/fdev-systemd.h index 2d573efe..ee46186a 100644 --- a/src/fdev-systemd.h +++ b/src/fdev-systemd.h @@ -21,3 +21,4 @@ struct fdev; struct sd_event; extern struct fdev *fdev_systemd_create(struct sd_event *eloop, int fd); + @@ -22,20 +22,14 @@ #include <unistd.h> #include <signal.h> #include <string.h> -#include <time.h> -#include <sys/syscall.h> #include <pthread.h> #include <errno.h> #include <assert.h> -#include <sys/eventfd.h> - -#include <systemd/sd-event.h> #include "jobs.h" #include "evmgr.h" #include "sig-monitor.h" #include "verbose.h" -#include "systemd.h" #define EVENT_TIMEOUT_TOP ((uint64_t)-1) #define EVENT_TIMEOUT_CHILD ((uint64_t)10000) @@ -715,7 +709,7 @@ int jobs_call( /** * Ensure that the current running thread can control the event loop. */ -void jobs_acquire_event_manager() +struct evmgr *jobs_acquire_event_manager() { struct thread lt; @@ -755,6 +749,7 @@ void jobs_acquire_event_manager() evloop_release(); current_thread = NULL; } + return evmgr; } /** @@ -18,6 +18,7 @@ #pragma once struct jobloop; +struct evmgr; extern int jobs_queue( const void *group, @@ -46,6 +47,6 @@ extern int jobs_start( void (*start)(int signum, void* arg), void *arg); -extern void jobs_acquire_event_manager(); +extern struct evmgr *jobs_acquire_event_manager(); extern void jobs_exit(void (*handler)()); diff --git a/src/main-afb-daemon.c b/src/main-afb-daemon.c index d825d803..705c69f9 100644 --- a/src/main-afb-daemon.c +++ b/src/main-afb-daemon.c @@ -36,7 +36,9 @@ #include <json-c/json.h> -#include <systemd/sd-daemon.h> +#if WITH_SYSTEMD +# include <systemd/sd-daemon.h> +#endif #include "afb-args.h" #include "afb-hswitch.h" @@ -885,7 +887,9 @@ static void start(int signum, void *arg) goto error; /* ready */ +#if WITH_SYSTEMD sd_notify(1, "READY=1"); +#endif /* activate the watchdog */ #if HAS_WATCHDOG diff --git a/src/systemd.c b/src/systemd.c index 29d626bc..747e6a83 100644 --- a/src/systemd.c +++ b/src/systemd.c @@ -15,6 +15,8 @@ * limitations under the License. */ +#if WITH_SYSTEMD + #define _GNU_SOURCE #include <unistd.h> @@ -113,3 +115,4 @@ int systemd_fds_for(const char *name) return -1; } +#endif diff --git a/src/systemd.h b/src/systemd.h index d9efa352..0fadfa7d 100644 --- a/src/systemd.h +++ b/src/systemd.h @@ -17,6 +17,8 @@ #pragma once +#if WITH_SYSTEMD + struct sd_event; struct sd_bus; @@ -27,4 +29,4 @@ extern struct sd_bus *systemd_get_system_bus(); extern int systemd_fds_init(); extern int systemd_fds_for(const char *name); - +#endif diff --git a/src/watchdog.c b/src/watchdog.c index 92144ba0..1aa9a51e 100644 --- a/src/watchdog.c +++ b/src/watchdog.c @@ -23,19 +23,26 @@ #include <stdlib.h> +#include "jobs.h" + +#if WITH_SYSTEMD + #include <systemd/sd-event.h> #include <systemd/sd-daemon.h> -#include "jobs.h" #include "systemd.h" +#endif + int watchdog_activate() { +#if WITH_SYSTEMD /* set the watchdog */ if (sd_watchdog_enabled(0, NULL)) { jobs_acquire_event_manager(); sd_event_set_watchdog(systemd_get_event_loop(), 1); } +#endif return 0; } |