#include "rtnl-util.h"
static int sd_rtnl_new(sd_rtnl **ret) {
- sd_rtnl *rtnl;
+ _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
assert_return(ret, -EINVAL);
/* We guarantee that wqueue always has space for at least
* one entry */
rtnl->wqueue = new(sd_rtnl_message*, 1);
- if (!rtnl->wqueue) {
- free(rtnl);
+ if (!rtnl->wqueue)
return -ENOMEM;
- }
*ret = rtnl;
+ rtnl = NULL;
+
return 0;
}
}
sd_rtnl *sd_rtnl_ref(sd_rtnl *rtnl) {
+ assert_return(rtnl, NULL);
+ assert_return(!rtnl_pid_changed(rtnl), NULL);
+
if (rtnl)
assert_se(REFCNT_INC(rtnl->n_ref) >= 2);
}
sd_rtnl *sd_rtnl_unref(sd_rtnl *rtnl) {
+ if (!rtnl)
+ return NULL;
+
+ assert_return(!rtnl_pid_changed(rtnl), NULL);
- if (rtnl && REFCNT_DEC(rtnl->n_ref) <= 0) {
+ if (REFCNT_DEC(rtnl->n_ref) <= 0) {
struct match_callback *f;
unsigned i;
hashmap_free_free(rtnl->reply_callbacks);
prioq_free(rtnl->reply_callbacks_prioq);
+ sd_event_source_unref(rtnl->io_event_source);
+ sd_event_source_unref(rtnl->time_event_source);
+ sd_event_source_unref(rtnl->exit_event_source);
+ sd_event_unref(rtnl->event);
+
while ((f = rtnl->match_callbacks)) {
LIST_REMOVE(match_callbacks, rtnl->match_callbacks, f);
free(f);
return NULL;
}
+static void rtnl_seal_message(sd_rtnl *rtnl, sd_rtnl_message *m) {
+ assert(rtnl);
+ assert(!rtnl_pid_changed(rtnl));
+ assert(m);
+ assert(m->hdr);
+
+ m->hdr->nlmsg_seq = rtnl->serial++;
+
+ rtnl_message_seal(m);
+
+ return;
+}
+
int sd_rtnl_send(sd_rtnl *nl,
sd_rtnl_message *message,
uint32_t *serial) {
assert_return(nl, -EINVAL);
assert_return(!rtnl_pid_changed(nl), -ECHILD);
assert_return(message, -EINVAL);
+ assert_return(!message->sealed, -EPERM);
- r = rtnl_message_seal(nl, message);
- if (r < 0)
- return r;
+ rtnl_seal_message(nl, message);
if (nl->wqueue_size <= 0) {
/* send directly */
/* Try to read a new message */
r = socket_read_message(rtnl, &z);
- if (r < 0)
+ if (r <= 0)
return r;
- if (r == 0)
- return 0;
*message = z;
if (r < 0)
goto fail;
- r = sd_event_add_monotonic(rtnl->event, &rtnl->time_event_source, 0, 0, time_callback, rtnl);
+ r = sd_event_add_time(rtnl->event, &rtnl->time_event_source, CLOCK_MONOTONIC, 0, 0, time_callback, rtnl);
if (r < 0)
goto fail;