return afb_evt_broadcast(event, object);
}
+static struct sd_event *get_event_loop(struct afb_api_x3 *closure)
+{
+ jobs_acquire_event_manager();
+ return systemd_get_event_loop();
+}
+
+static struct sd_bus *get_user_bus(struct afb_api_x3 *closure)
+{
+ jobs_acquire_event_manager();
+ return systemd_get_user_bus();
+}
+
+static struct sd_bus *get_system_bus(struct afb_api_x3 *closure)
+{
+ jobs_acquire_event_manager();
+ return systemd_get_system_bus();
+}
+
static int rootdir_open_locale_cb(struct afb_api_x3 *closure, const char *filename, int flags, const char *locale)
{
return afb_common_rootdir_open_locale(filename, flags, locale);
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 = systemd_get_event_loop();
+ struct sd_event *r;
+
+ jobs_acquire_event_manager();
+ r = get_event_loop(closure);
return afb_hook_api_get_event_loop(export, r);
}
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 = systemd_get_user_bus();
+ struct sd_bus *r;
+
+ jobs_acquire_event_manager();
+ r = get_user_bus(closure);
return afb_hook_api_get_user_bus(export, r);
}
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 = systemd_get_system_bus();
+ struct sd_bus *r;
+
+ jobs_acquire_event_manager();
+ r = get_system_bus(closure);
return afb_hook_api_get_system_bus(export, r);
}
.vverbose_v2 = vverbose_cb,
.event_make = legacy_event_x1_make_cb,
.event_broadcast = event_broadcast_cb,
- .get_event_loop = systemd_get_event_loop,
- .get_user_bus = systemd_get_user_bus,
- .get_system_bus = systemd_get_system_bus,
+ .get_event_loop = get_event_loop,
+ .get_user_bus = get_user_bus,
+ .get_system_bus = get_system_bus,
.rootdir_get_fd = afb_common_rootdir_get_fd,
.rootdir_open_locale = rootdir_open_locale_cb,
.queue_job = queue_job_cb,
.vverbose = (void*)vverbose_cb,
- .get_event_loop = systemd_get_event_loop,
- .get_user_bus = systemd_get_user_bus,
- .get_system_bus = systemd_get_system_bus,
+ .get_event_loop = get_event_loop,
+ .get_user_bus = get_user_bus,
+ .get_system_bus = get_system_bus,
.rootdir_get_fd = afb_common_rootdir_get_fd,
.rootdir_open_locale = rootdir_open_locale_cb,
.queue_job = queue_job_cb,
#include "jobs.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)
goto error1;
}
/* create the systemd event loop */
- rc = sd_event_new(&evloop.sdev);
- if (rc < 0) {
- ERROR("can't make new event loop");
+ evloop.sdev = systemd_get_event_loop();
+ if (!evloop.sdev) {
+ ERROR("can't make event loop");
goto error2;
}
/* put the eventfd in the event loop */
rc = sd_event_add_io(evloop.sdev, NULL, evloop.efd, EPOLLIN, on_evloop_efd, NULL);
if (rc < 0) {
ERROR("can't register eventfd");
- sd_event_unref(evloop.sdev);
evloop.sdev = NULL;
error2:
close(evloop.efd);
}
/**
- * Gets a sd_event item for the current thread.
- * @return a sd_event or NULL in case of error
+ * Ensure that the current running thread can control the event loop.
*/
-struct sd_event *jobs_get_sd_event()
+void jobs_acquire_event_manager()
{
- struct sd_event *result;
struct thread lt;
/* ensure an existing thread environment */
/* process */
pthread_mutex_lock(&mutex);
- result = get_sd_event_locked();
+ get_sd_event_locked();
pthread_mutex_unlock(&mutex);
/* release the faked thread environment if needed */
evloop_release();
current_thread = NULL;
}
-
- return result;
}
/**
#include <systemd/sd-daemon.h>
#include "systemd.h"
-#include "jobs.h"
static struct sd_bus *sdbusopen(struct sd_bus **p, int (*f)(struct sd_bus **))
{
- if (*p == NULL) {
- int rc = f(p);
- if (rc < 0) {
- errno = -rc;
- *p = NULL;
- } else {
- rc = sd_bus_attach_event(*p, systemd_get_event_loop(), 0);
+ int rc;
+ struct sd_bus *r;
+
+ r = *p;
+ if (!r) {
+ rc = f(&r);
+ if (rc >= 0) {
+ rc = sd_bus_attach_event(r, systemd_get_event_loop(), 0);
if (rc < 0) {
- sd_bus_unref(*p);
- errno = -rc;
- *p = NULL;
+ sd_bus_unref(r);
+ r = 0;
}
}
+ if (rc < 0)
+ errno = -rc;
+ *p = r;
}
- return *p;
+ return r;
}
struct sd_event *systemd_get_event_loop()
{
- return jobs_get_sd_event();
+ static struct sd_event *result = 0;
+ int rc;
+
+ if (!result) {
+ rc = sd_event_new(&result);
+ if (rc < 0) {
+ errno = -rc;
+ result = NULL;
+ }
+ }
+ return result;
}
struct sd_bus *systemd_get_user_bus()
{
- static struct sd_bus *result = NULL;
+ static struct sd_bus *result = 0;
return sdbusopen((void*)&result, (void*)sd_bus_open_user);
}
struct sd_bus *systemd_get_system_bus()
{
- static struct sd_bus *result = NULL;
+ static struct sd_bus *result = 0;
return sdbusopen((void*)&result, (void*)sd_bus_open_system);
}