sd-event.c revision ec202eae8e84a4c99f054f771cb832046cb8769f
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2013 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define DEFAULT_ACCURACY_USEC (250 * USEC_PER_MSEC)
4e724d9c5ab76c3f8327945317463ef706011082Lennart Poettering /* For both clocks we maintain two priority queues each, one
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering * ordered for the earliest times the events may be
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering * dispatched, and one ordered by the latest times they must
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering * have been dispatched. The range between the top entries in
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering * the two prioqs is the time window we can freely schedule
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering * wakeups in */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringstatic int pending_prioq_compare(const void *a, const void *b) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering const sd_event_source *x = a, *y = b;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Enabled ones first */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* Lower priority values first */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Older entries first */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (x->pending_iteration < y->pending_iteration)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (x->pending_iteration > y->pending_iteration)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Stability for the rest */
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poetteringstatic int prepare_prioq_compare(const void *a, const void *b) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const sd_event_source *x = a, *y = b;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Move most recently prepared ones last, so that we can stop
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * preparing as soon as we hit one that has already been
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * prepared in the current iteration */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (x->prepare_iteration < y->prepare_iteration)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (x->prepare_iteration > y->prepare_iteration)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering /* Enabled ones first */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Lower priority values first */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Stability for the rest */
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poetteringstatic int earliest_time_prioq_compare(const void *a, const void *b) {
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering const sd_event_source *x = a, *y = b;
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering assert(x->type == SOURCE_MONOTONIC || x->type == SOURCE_REALTIME);
5b12334d35eadf1f45cc3d631fd1a2e72ffaea0aLennart Poettering assert(y->type == SOURCE_MONOTONIC || y->type == SOURCE_REALTIME);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* Enabled ones first */
554604b3073467af75dc94fac9e2343148603289Lennart Poettering if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
554604b3073467af75dc94fac9e2343148603289Lennart Poettering /* Move the pending ones to the end */
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering /* Order by time */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Stability for the rest */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int latest_time_prioq_compare(const void *a, const void *b) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const sd_event_source *x = a, *y = b;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert((x->type == SOURCE_MONOTONIC && y->type == SOURCE_MONOTONIC) ||
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (x->type == SOURCE_REALTIME && y->type == SOURCE_REALTIME));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Enabled ones first */
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Move the pending ones to the end */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Order by time */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (x->time.next + x->time.accuracy < y->time.next + y->time.accuracy)
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering if (x->time.next + x->time.accuracy > y->time.next + y->time.accuracy)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* Stability for the rest */
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poetteringstatic int exit_prioq_compare(const void *a, const void *b) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const sd_event_source *x = a, *y = b;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* Enabled ones first */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (x->enabled == SD_EVENT_OFF && y->enabled != SD_EVENT_OFF)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Lower priority values first */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* Stability for the rest */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering_public_ int sd_event_new(sd_event** ret) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering e->signal_fd = e->realtime_fd = e->monotonic_fd = e->watchdog_fd = e->epoll_fd = -1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering e->realtime_next = e->monotonic_next = (usec_t) -1;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering e->pending = prioq_new(pending_prioq_compare);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering e->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering_public_ sd_event* sd_event_ref(sd_event *e) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering_public_ sd_event* sd_event_unref(sd_event *e) {
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poetteringstatic bool event_pid_changed(sd_event *e) {
554604b3073467af75dc94fac9e2343148603289Lennart Poettering /* We don't support people creating am event loop and keeping
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering * it around over a fork(). Let's complain. */
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poetteringstatic int source_io_unregister(sd_event_source *s) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, s->io.fd, NULL);
ebcf1f97de4f6b1580ae55eb56b1a3939fe6b602Lennart Poettering r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_MOD, s->io.fd, &ev);
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering r = epoll_ctl(s->event->epoll_fd, EPOLL_CTL_ADD, s->io.fd, &ev);
554604b3073467af75dc94fac9e2343148603289Lennart Poetteringstatic void source_free(sd_event_source *s) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prioq_remove(s->event->monotonic_earliest, s, &s->time.earliest_index);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prioq_remove(s->event->monotonic_latest, s, &s->time.latest_index);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering prioq_remove(s->event->realtime_earliest, s, &s->time.earliest_index);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prioq_remove(s->event->realtime_latest, s, &s->time.latest_index);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (s->signal.sig != SIGCHLD || s->event->n_enabled_child_sources == 0)
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_se(sigdelset(&s->event->sigset, s->signal.sig) == 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering s->event->signal_sources[s->signal.sig] = NULL;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert(s->event->n_enabled_child_sources > 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!s->event->signal_sources || !s->event->signal_sources[SIGCHLD])
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sigdelset(&s->event->sigset, SIGCHLD) == 0);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering hashmap_remove(s->event->child_sources, INT_TO_PTR(s->child.pid));
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering prioq_remove(s->event->exit, s, &s->exit.prioq_index);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_not_reached("Wut? I shouldn't exist.");
554604b3073467af75dc94fac9e2343148603289Lennart Poettering prioq_remove(s->event->pending, s, &s->pending_index);
554604b3073467af75dc94fac9e2343148603289Lennart Poettering prioq_remove(s->event->prepare, s, &s->prepare_index);
c49b30a23583ff39daaa26696bcab478d2fee0bbLennart Poetteringstatic int source_set_pending(sd_event_source *s, bool b) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s->pending_iteration = s->event->iteration;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = prioq_put(s->event->pending, s, &s->pending_index);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(prioq_remove(s->event->pending, s, &s->pending_index));
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering prioq_reshuffle(s->event->realtime_earliest, s, &s->time.earliest_index);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prioq_reshuffle(s->event->realtime_latest, s, &s->time.latest_index);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (s->type == SOURCE_MONOTONIC) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prioq_reshuffle(s->event->monotonic_earliest, s, &s->time.earliest_index);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prioq_reshuffle(s->event->monotonic_latest, s, &s->time.latest_index);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic sd_event_source *source_new(sd_event *e, EventSourceType type) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering s->pending_index = s->prepare_index = PRIOQ_IDX_NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_return(!event_pid_changed(e), -ECHILD);
a658cafa98ab55ea948c29bc87eb3945d515fb41Lennart Poettering r = source_io_register(s, s->enabled, events);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering fd = timerfd_create(id, TFD_NONBLOCK|TFD_CLOEXEC);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering r = epoll_ctl(e->epoll_fd, EPOLL_CTL_ADD, fd, &ev);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering /* When we sleep for longer, we try to realign the wakeup to
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering the same time wihtin each minute/second/250ms, so that
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering events all across the system can be coalesced into a single
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering CPU wakeup. However, let's take some system-specific
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering randomness for this value, so that in a network of systems
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering with synced clocks timer events are distributed a
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek bit. Here, we calculate a perturbation usec offset from the
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering e->perturb = (bootid.qwords[0] ^ bootid.qwords[1]) % USEC_PER_MINUTE;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_return(usec != (uint64_t) -1, -EINVAL);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_return(accuracy != (uint64_t) -1, -EINVAL);
bd16acf35e13a19cd2ded0a0c2ef774a98f73808Zbigniew Jędrzejewski-Szmek assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_return(!event_pid_changed(e), -ECHILD);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers *earliest = prioq_new(earliest_time_prioq_compare);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers r = event_setup_timer_fd(e, type, timer_fd, id);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers s->time.accuracy = accuracy == 0 ? DEFAULT_ACCURACY_USEC : accuracy;
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers s->time.earliest_index = s->time.latest_index = PRIOQ_IDX_NULL;
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers r = prioq_put(*earliest, s, &s->time.earliest_index);
ab49725fd8587ef2b90dd0a67b2c915bc772d089Kay Sievers r = prioq_put(*latest, s, &s->time.latest_index);
*ret = s;
fail:
source_free(s);
void *userdata,
return event_add_time_internal(e, SOURCE_MONOTONIC, &e->monotonic_fd, CLOCK_MONOTONIC, &e->monotonic_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata, ret);
void *userdata,
return event_add_time_internal(e, SOURCE_REALTIME, &e->realtime_fd, CLOCK_REALTIME, &e->realtime_earliest, &e->monotonic_latest, usec, accuracy, callback, userdata, ret);
bool add_to_epoll;
assert(e);
return -errno;
e->signal_fd = r;
if (!add_to_epoll)
return -errno;
sd_event *e,
int sig,
void *userdata,
sd_event_source *s;
if (!e->signal_sources) {
if (!e->signal_sources)
return -ENOMEM;
return -EBUSY;
return -ENOMEM;
r = event_update_signal_fd(e);
source_free(s);
*ret = s;
sd_event *e,
int options,
void *userdata,
sd_event_source *s;
return -EBUSY;
return -ENOMEM;
source_free(s);
e->n_enabled_child_sources ++;
r = event_update_signal_fd(e);
source_free(s);
return -errno;
e->need_process_child = true;
*ret = s;
sd_event *e,
void *userdata,
sd_event_source *s;
return -ENOMEM;
r = source_set_pending(s, true);
source_free(s);
*ret = s;
sd_event *e,
void *userdata,
sd_event_source *s;
if (!e->exit) {
if (!e->exit)
return -ENOMEM;
return -ENOMEM;
source_free(s);
*ret = s;
s->n_ref++;
return NULL;
s->n_ref--;
if (s->n_ref <= 0) {
if (s->dispatching) {
source_free(s);
return NULL;
return s->event;
return s->pending;
int saved_fd;
assert_return(!(events & ~(EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET)), -EINVAL);
source_set_pending(s, false);
return s->priority;
if (s->pending)
if (s->prepare)
*m = s->enabled;
if (s->enabled == m)
if (m == SD_EVENT_OFF) {
switch (s->type) {
case SOURCE_IO:
r = source_io_unregister(s);
s->enabled = m;
case SOURCE_MONOTONIC:
s->enabled = m;
case SOURCE_REALTIME:
s->enabled = m;
case SOURCE_SIGNAL:
s->enabled = m;
case SOURCE_CHILD:
s->enabled = m;
case SOURCE_EXIT:
s->enabled = m;
case SOURCE_DEFER:
s->enabled = m;
case SOURCE_WATCHDOG:
switch (s->type) {
case SOURCE_IO:
s->enabled = m;
case SOURCE_MONOTONIC:
s->enabled = m;
case SOURCE_REALTIME:
s->enabled = m;
case SOURCE_SIGNAL:
s->enabled = m;
case SOURCE_CHILD:
s->enabled = m;
case SOURCE_EXIT:
s->enabled = m;
case SOURCE_DEFER:
s->enabled = m;
case SOURCE_WATCHDOG:
if (s->pending)
if (s->prepare)
source_set_pending(s, false);
if (usec == 0)
source_set_pending(s, false);
if (callback) {
return s->userdata;
void *ret;
return ret;
usec_t c;
assert(e);
assert(a <= b);
c -= USEC_PER_MINUTE;
c -= USEC_PER_SEC;
static int event_arm_timer(
sd_event *e,
int timer_fd,
sd_event_source *a, *b;
usec_t t;
assert(e);
if (timer_fd < 0)
if (*next == t)
return -errno;
*next = t;
assert(e);
assert(s);
if (s->pending)
return source_set_pending(s, true);
uint64_t x;
assert(e);
if (ss < 0) {
return -errno;
return -EIO;
if (next)
static int process_timer(
sd_event *e,
usec_t n,
sd_event_source *s;
assert(e);
s->pending)
r = source_set_pending(s, true);
sd_event_source *s;
Iterator i;
assert(e);
e->need_process_child = false;
if (s->pending)
return -errno;
bool zombie =
r = source_set_pending(s, true);
bool read_one = false;
assert(e);
sd_event_source *s;
if (ss < 0) {
return read_one;
return -errno;
return -EIO;
read_one = true;
r = process_child(e);
return -EIO;
r = source_set_pending(s, true);
assert(s);
r = source_set_pending(s, false);
s->dispatching = true;
switch (s->type) {
case SOURCE_IO:
case SOURCE_MONOTONIC:
case SOURCE_REALTIME:
case SOURCE_SIGNAL:
case SOURCE_CHILD: {
bool zombie;
if (zombie)
case SOURCE_DEFER:
case SOURCE_EXIT:
case SOURCE_WATCHDOG:
s->dispatching = false;
if (s->n_ref == 0)
source_free(s);
assert(e);
sd_event_source *s;
s->dispatching = true;
s->dispatching = false;
if (s->n_ref == 0)
source_free(s);
sd_event_source *p;
assert(e);
sd_event_ref(e);
e->iteration++;
r = source_dispatch(p);
sd_event_unref(e);
sd_event_source *p;
assert(e);
return NULL;
return NULL;
usec_t t;
assert(e);
t = sleep_between(e,
return -errno;
assert(e);
if (!e->watchdog)
return arm_watchdog(e);
unsigned ev_queue_max;
sd_event_source *p;
if (e->exit_requested)
return dispatch_exit(e);
sd_event_ref(e);
e->iteration++;
r = event_prepare(e);
goto finish;
r = event_arm_timer(e, e->monotonic_fd, e->monotonic_earliest, e->monotonic_latest, &e->monotonic_next);
goto finish;
r = event_arm_timer(e, e->realtime_fd, e->realtime_earliest, e->realtime_latest, &e->realtime_next);
goto finish;
timeout = 0;
goto finish;
goto finish;
r = process_watchdog(e);
goto finish;
goto finish;
goto finish;
if (e->need_process_child) {
r = process_child(e);
goto finish;
p = event_next_pending(e);
goto finish;
r = source_dispatch(p);
sd_event_unref(e);
sd_event_ref(e);
goto finish;
r = e->exit_code;
sd_event_unref(e);
return e->state;
if (!e->exit_requested)
return -ENODATA;
e->exit_requested = true;
sd_event *e;
if (!ret)
return !!default_event;
if (default_event) {
r = sd_event_new(&e);
default_event = e;
*ret = e;
if (e->tid != 0) {
return -ENXIO;
if (e->watchdog == !!b)
return e->watchdog;
const char *env;
if (!env)
if (e->watchdog_period <= 0)
return -EIO;
if (e->watchdog_fd < 0)
return -errno;
r = arm_watchdog(e);
goto fail;
r = -errno;
goto fail;
if (e->watchdog_fd >= 0) {
e->watchdog = !!b;
return e->watchdog;
fail:
return e->watchdog;