blob: 9863b07653f71a005cb6669a753e5d2d88a044d4 [file] [log] [blame]
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
#include "event-source.h"
#include "event-util.h"
#include "fd-util.h"
#include "log.h"
#include "string-util.h"
int event_reset_time(
sd_event *e,
sd_event_source **s,
clockid_t clock,
uint64_t usec,
uint64_t accuracy,
sd_event_time_handler_t callback,
void *userdata,
int64_t priority,
const char *description,
bool force_reset) {
bool created = false;
int enabled, r;
clockid_t c;
assert(e);
assert(s);
if (*s) {
if (!force_reset) {
r = sd_event_source_get_enabled(*s, &enabled);
if (r < 0)
return log_debug_errno(r, "sd-event: Failed to query whether event source \"%s\" is enabled or not: %m",
strna((*s)->description ?: description));
if (enabled != SD_EVENT_OFF)
return 0;
}
r = sd_event_source_get_time_clock(*s, &c);
if (r < 0)
return log_debug_errno(r, "sd-event: Failed to get clock id of event source \"%s\": %m", strna((*s)->description ?: description));
if (c != clock)
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"sd-event: Current clock id %i of event source \"%s\" is different from specified one %i.",
(int)c,
strna((*s)->description ? : description),
(int)clock);
r = sd_event_source_set_time(*s, usec);
if (r < 0)
return log_debug_errno(r, "sd-event: Failed to set time for event source \"%s\": %m", strna((*s)->description ?: description));
r = sd_event_source_set_time_accuracy(*s, accuracy);
if (r < 0)
return log_debug_errno(r, "sd-event: Failed to set accuracy for event source \"%s\": %m", strna((*s)->description ?: description));
/* callback function is not updated, as we do not have sd_event_source_set_time_callback(). */
(void) sd_event_source_set_userdata(*s, userdata);
r = sd_event_source_set_enabled(*s, SD_EVENT_ONESHOT);
if (r < 0)
return log_debug_errno(r, "sd-event: Failed to enable event source \"%s\": %m", strna((*s)->description ?: description));
} else {
r = sd_event_add_time(e, s, clock, usec, accuracy, callback, userdata);
if (r < 0)
return log_debug_errno(r, "sd-event: Failed to create timer event \"%s\": %m", strna(description));
created = true;
}
r = sd_event_source_set_priority(*s, priority);
if (r < 0)
return log_debug_errno(r, "sd-event: Failed to set priority for event source \"%s\": %m", strna((*s)->description ?: description));
if (description) {
r = sd_event_source_set_description(*s, description);
if (r < 0)
return log_debug_errno(r, "sd-event: Failed to set description for event source \"%s\": %m", description);
}
return created;
}
int event_reset_time_relative(
sd_event *e,
sd_event_source **s,
clockid_t clock,
uint64_t usec,
uint64_t accuracy,
sd_event_time_handler_t callback,
void *userdata,
int64_t priority,
const char *description,
bool force_reset) {
usec_t usec_now;
int r;
assert(e);
r = sd_event_now(e, clock, &usec_now);
if (r < 0)
return log_debug_errno(r, "sd-event: Failed to get the current time: %m");
return event_reset_time(e, s, clock, usec_add(usec_now, usec), accuracy, callback, userdata, priority, description, force_reset);
}
int event_add_time_change(sd_event *e, sd_event_source **ret, sd_event_io_handler_t callback, void *userdata) {
_cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
_cleanup_close_ int fd = -EBADF;
int r;
assert(e);
/* Allocates an IO event source that gets woken up whenever the clock changes. Needs to be recreated on each event */
fd = time_change_fd();
if (fd < 0)
return fd;
r = sd_event_add_io(e, &s, fd, EPOLLIN, callback, userdata);
if (r < 0)
return r;
r = sd_event_source_set_io_fd_own(s, true);
if (r < 0)
return r;
TAKE_FD(fd);
r = sd_event_source_set_description(s, "time-change");
if (r < 0)
return r;
if (ret)
*ret = TAKE_PTR(s);
else {
r = sd_event_source_set_floating(s, true);
if (r < 0)
return r;
}
return 0;
}