From 2155907fa475d3d3f986fb862d039c2e98a9e8bb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Vladim=C3=ADr=20=C4=8Cun=C3=A1t?= Date: Mon, 24 Jun 2019 14:44:26 +0200 Subject: [PATCH] modules/sd_watchdog: deinit correctness and slightly better error reporting. --- lib/utils.c | 5 +++++ lib/utils.h | 4 ++++ modules/sd_watchdog/sd_watchdog.c | 20 +++++++++++++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/utils.c b/lib/utils.c index 780805ea8..0200b144c 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -963,6 +963,11 @@ uint64_t kr_now() return uv_now(uv_default_loop()); } +void kr_uv_free_cb(uv_handle_t* handle) +{ + free(handle->data); +} + const char *kr_strptime_diff(const char *format, const char *time1_str, const char *time0_str, double *diff) { assert(format != NULL); diff --git a/lib/utils.h b/lib/utils.h index 5b376c6e8..7b8079c75 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -30,6 +30,7 @@ #include #include #include +#include #include "kresconfig.h" #include "lib/generic/array.h" @@ -478,6 +479,9 @@ static inline uint16_t kr_rrset_type_maysig(const knot_rrset_t *rr) KR_EXPORT uint64_t kr_now(); +/** Call free(handle->data); it's useful e.g. as a callback in uv_close(). */ +KR_EXPORT void kr_uv_free_cb(uv_handle_t* handle); + /** Convert name from lookup format to wire. See knot_dname_lf * * \note len bytes are read and len+1 are written with *normal* LF, diff --git a/modules/sd_watchdog/sd_watchdog.c b/modules/sd_watchdog/sd_watchdog.c index bdf6f51f4..76f0a96df 100644 --- a/modules/sd_watchdog/sd_watchdog.c +++ b/modules/sd_watchdog/sd_watchdog.c @@ -17,6 +17,7 @@ struct watchdog_config { static void keepalive_ping(uv_timer_t *timer) { // NOTE: in the future, some sanity checks could be used here + // It is generally recommended to ignore the return value of this call. sd_notify(0, "WATCHDOG=1"); } @@ -51,7 +52,9 @@ int sd_watchdog_init(struct kr_module *module) uv_timer_init(loop, &conf->timer); ret = uv_timer_start(&conf->timer, keepalive_ping, delay_ms, delay_ms); if (ret != 0) { - kr_log_error("[sd_watchdog] error: failed to start uv_timer!\n"); + kr_log_error("[sd_watchdog] error: failed to start uv_timer: %s\n", + uv_strerror(ret)); + conf->timer.loop = NULL; return kr_error(ret); } @@ -64,8 +67,19 @@ int sd_watchdog_init(struct kr_module *module) KR_EXPORT int sd_watchdog_deinit(struct kr_module *module) { - struct stat_data *conf = module->data; - if (conf) { + struct watchdog_config *conf = module->data; + if (conf && conf->timer.loop == uv_default_loop()) { /* normal state */ + int ret = uv_timer_stop(&conf->timer); + if (ret != 0) { + kr_log_error("[sd_watchdog] error: failed to stop uv_timer: %s\n", + uv_strerror(ret)); + } + /* We have a problem: UV timer can't be closed immediately, + * but as soon as we return from _deinit(), we get dlclose() + * so no function from this module may be usable anymore. */ + conf->timer.data = conf; + uv_close((uv_handle_t *)&conf->timer, kr_uv_free_cb); + } else { /* watchdog might be just disabled */ free(conf); } return kr_ok(); -- 2.47.2