sd-netlink: add destroy_callback argument to sd_netlink_call_async()

This commit is contained in:
Yu Watanabe
2018-10-10 14:43:05 +09:00
parent 2fea60901d
commit 545bab1f0a
16 changed files with 75 additions and 54 deletions
@@ -23,6 +23,7 @@ struct reply_callback {
usec_t timeout;
uint64_t serial;
unsigned prioq_idx;
sd_netlink_destroy_t destroy_callback;
};
struct match_callback {
+37 -20
View File
@@ -148,6 +148,7 @@ int sd_netlink_inc_rcvbuf(sd_netlink *rtnl, size_t size) {
}
static sd_netlink *netlink_free(sd_netlink *rtnl) {
struct reply_callback *c;
struct match_callback *f;
unsigned i;
@@ -163,7 +164,12 @@ static sd_netlink *netlink_free(sd_netlink *rtnl) {
free(rtnl->rbuffer);
hashmap_free_free(rtnl->reply_callbacks);
while ((c = hashmap_steal_first(rtnl->reply_callbacks))) {
if (c->destroy_callback)
c->destroy_callback(c->userdata);
free(c);
}
hashmap_free(rtnl->reply_callbacks);
prioq_free(rtnl->reply_callbacks_prioq);
sd_event_source_unref(rtnl->io_event_source);
@@ -299,6 +305,9 @@ static int process_timeout(sd_netlink *rtnl) {
if (r < 0)
log_debug_errno(r, "sd-netlink: timedout callback failed: %m");
if (c->destroy_callback)
c->destroy_callback(c->userdata);
free(c);
return 1;
@@ -332,6 +341,9 @@ static int process_reply(sd_netlink *rtnl, sd_netlink_message *m) {
if (r < 0)
log_debug_errno(r, "sd-netlink: callback failed: %m");
if (c->destroy_callback)
c->destroy_callback(c->userdata);
return 1;
}
@@ -494,13 +506,15 @@ static int timeout_compare(const void *a, const void *b) {
return CMP(x->timeout, y->timeout);
}
int sd_netlink_call_async(sd_netlink *nl,
sd_netlink_message *m,
sd_netlink_message_handler_t callback,
void *userdata,
uint64_t usec,
uint32_t *serial) {
struct reply_callback *c;
int sd_netlink_call_async(
sd_netlink *nl,
sd_netlink_message *m,
sd_netlink_message_handler_t callback,
sd_netlink_destroy_t destroy_callback,
void *userdata,
uint64_t usec,
uint32_t *serial) {
_cleanup_free_ struct reply_callback *c = NULL;
uint32_t s;
int r, k;
@@ -519,33 +533,31 @@ int sd_netlink_call_async(sd_netlink *nl,
return r;
}
c = new0(struct reply_callback, 1);
c = new(struct reply_callback, 1);
if (!c)
return -ENOMEM;
c->callback = callback;
c->userdata = userdata;
c->timeout = calc_elapse(usec);
*c = (struct reply_callback) {
.callback = callback,
.userdata = userdata,
.timeout = calc_elapse(usec),
.destroy_callback = destroy_callback,
};
k = sd_netlink_send(nl, m, &s);
if (k < 0) {
free(c);
if (k < 0)
return k;
}
c->serial = s;
r = hashmap_put(nl->reply_callbacks, &c->serial, c);
if (r < 0) {
free(c);
if (r < 0)
return r;
}
if (c->timeout != 0) {
r = prioq_put(nl->reply_callbacks_prioq, c, &c->prioq_idx);
if (r < 0) {
c->timeout = 0;
sd_netlink_call_async_cancel(nl, c->serial);
(void) hashmap_remove(nl->reply_callbacks, &c->serial);
return r;
}
}
@@ -553,6 +565,8 @@ int sd_netlink_call_async(sd_netlink *nl,
if (serial)
*serial = s;
TAKE_PTR(c);
return k;
}
@@ -571,6 +585,9 @@ int sd_netlink_call_async_cancel(sd_netlink *nl, uint32_t serial) {
if (c->timeout != 0)
prioq_remove(nl->reply_callbacks_prioq, c, &c->prioq_idx);
if (c->destroy_callback)
c->destroy_callback(c->userdata);
free(c);
return 1;
}
+4 -4
View File
@@ -199,7 +199,7 @@ static void test_event_loop(int ifindex) {
assert_se(sd_netlink_open(&rtnl) >= 0);
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
assert_se(sd_netlink_call_async(rtnl, m, link_handler, ifname, 0, NULL) >= 0);
assert_se(sd_netlink_call_async(rtnl, m, link_handler, NULL, ifname, 0, NULL) >= 0);
assert_se(sd_event_default(&event) >= 0);
@@ -240,7 +240,7 @@ static void test_async(int ifindex) {
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
assert_se(sd_netlink_call_async(rtnl, m, link_handler, ifname, 0, &serial) >= 0);
assert_se(sd_netlink_call_async(rtnl, m, link_handler, NULL, ifname, 0, &serial) >= 0);
assert_se(sd_netlink_wait(rtnl, 0) >= 0);
assert_se(sd_netlink_process(rtnl, &r) >= 0);
@@ -259,10 +259,10 @@ static void test_pipe(int ifindex) {
assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0);
counter++;
assert_se(sd_netlink_call_async(rtnl, m1, pipe_handler, &counter, 0, NULL) >= 0);
assert_se(sd_netlink_call_async(rtnl, m1, pipe_handler, NULL, &counter, 0, NULL) >= 0);
counter++;
assert_se(sd_netlink_call_async(rtnl, m2, pipe_handler, &counter, 0, NULL) >= 0);
assert_se(sd_netlink_call_async(rtnl, m2, pipe_handler, NULL, &counter, 0, NULL) >= 0);
while (counter > 0) {
assert_se(sd_netlink_wait(rtnl, 0) >= 0);