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);
#include <libknot/packet/pkt.h>
#include <libknot/rrset.h>
#include <libknot/rrtype/rrsig.h>
+#include <uv.h>
#include "kresconfig.h"
#include "lib/generic/array.h"
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,
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");
}
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);
}
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();