From 008f1e5443f4f0b2d804198b4f22b2a914d4f69d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 9 Jul 2023 07:06:24 +0900 Subject: [PATCH] network/queue: detach request from queue when netlink reply received Then, we can find and use the Request object after sending netlink message. Preparation for later commits. --- src/network/networkd-queue.c | 24 ++++++++++++++++++++---- src/network/networkd-queue.h | 2 ++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index d5193538d89..90caefbc72c 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -12,7 +12,7 @@ static Request *request_free(Request *req) { return NULL; /* To prevent from triggering assertions in the hash and compare functions, remove this request - * before freeing userdata below. */ + * from the set before freeing userdata below. */ if (req->manager) ordered_set_remove(req->manager->request_queue, req); @@ -28,7 +28,6 @@ static Request *request_free(Request *req) { } DEFINE_TRIVIAL_REF_UNREF_FUNC(Request, request, request_free); -DEFINE_TRIVIAL_DESTRUCTOR(request_destroy_callback, Request, request_unref); void request_detach(Manager *manager, Request *req) { assert(manager); @@ -44,6 +43,15 @@ void request_detach(Manager *manager, Request *req) { request_unref(req); } +static void request_destroy_callback(Request *req) { + assert(req); + + if (req->manager) + request_detach(req->manager, req); + + request_unref(req); +} + static void request_hash_func(const Request *req, struct siphash *state) { assert(req); assert(state); @@ -205,17 +213,24 @@ int manager_process_requests(sd_event_source *s, void *userdata) { Request *req; ORDERED_SET_FOREACH(req, manager->request_queue) { - _unused_ _cleanup_(request_unrefp) Request *ref = request_ref(req); _cleanup_(link_unrefp) Link *link = link_ref(req->link); assert(req->process); + if (req->waiting_reply) + continue; /* Waiting for netlink reply. */ + r = req->process(req, link, req->userdata); if (r == 0) continue; processed = true; - request_detach(manager, req); + + /* If the request sends netlink message, e.g. for Address or so, the Request object + * is referenced by the netlink slot, and will be detached later by its destroy callback. + * Otherwise, e.g. for DHCP client or so, detach the request from queue now. */ + if (!req->waiting_reply) + request_detach(manager, req); if (r < 0 && link) { link_enter_failed(link); @@ -263,6 +278,7 @@ int request_call_netlink_async(sd_netlink *nl, sd_netlink_message *m, Request *r return r; request_ref(req); + req->waiting_reply = true; return 0; } diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h index 6db0005e619..e58d1be66f5 100644 --- a/src/network/networkd-queue.h +++ b/src/network/networkd-queue.h @@ -80,6 +80,8 @@ struct Request { * request, and pass this request to the netlink_call_async(), and set the destroy function * to the slot. */ request_netlink_handler_t netlink_handler; + + bool waiting_reply; }; Request *request_ref(Request *req); -- 2.47.3