From b9b5096edbb3c72b8b28378285542888ac0f4769 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 16 Jan 2024 14:04:50 +0900 Subject: [PATCH] network/queue: detach request from the queue only when the request is actually queued No effective functionality is changed in this commit. Refactoring and preparation for later commits. --- src/network/networkd-address.c | 2 +- src/network/networkd-link.c | 2 +- src/network/networkd-queue.c | 42 ++++++++++++++++------------------ src/network/networkd-queue.h | 2 +- src/network/networkd-route.c | 23 +++++++++++-------- 5 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 4c3393645e..fc6a708f87 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -1193,7 +1193,7 @@ int address_remove_and_cancel(Address *address, Link *link) { * notification about the request, then explicitly remove the address. */ if (address_get_request(link, address, &req) >= 0) { waiting = req->waiting_reply; - request_detach(link->manager, req); + request_detach(req); address_cancel_requesting(address); } diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 9e69624fd2..a39477e78b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -987,7 +987,7 @@ static int link_drop_requests(Link *link) { ; } - request_detach(link->manager, req); + request_detach(req); } return ret; diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index d1e9fec57a..383f259fa7 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -9,14 +9,28 @@ #define REPLY_CALLBACK_COUNT_THRESHOLD 128 +static Request* request_detach_impl(Request *req) { + assert(req); + + if (!req->manager) + return NULL; + + ordered_set_remove(req->manager->request_queue, req); + req->manager = NULL; + return req; +} + +void request_detach(Request *req) { + request_unref(request_detach_impl(req)); +} + static Request *request_free(Request *req) { if (!req) return NULL; /* To prevent from triggering assertions in the hash and compare functions, remove this request * from the set before freeing userdata below. */ - if (req->manager) - ordered_set_remove(req->manager->request_queue, req); + request_detach_impl(req); if (req->free_func) req->free_func(req->userdata); @@ -31,26 +45,10 @@ static Request *request_free(Request *req) { DEFINE_TRIVIAL_REF_UNREF_FUNC(Request, request, request_free); -void request_detach(Manager *manager, Request *req) { - assert(manager); - - if (!req) - return; - - req = ordered_set_remove(manager->request_queue, req); - if (!req) - return; - - req->manager = NULL; - request_unref(req); -} - static void request_destroy_callback(Request *req) { assert(req); - if (req->manager) - request_detach(req->manager, req); - + request_detach(req); request_unref(req); } @@ -114,7 +112,7 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR( Request, request_hash_func, request_compare_func, - request_unref); + request_detach); static int request_new( Manager *manager, @@ -248,7 +246,7 @@ int manager_process_requests(Manager *manager) { assert(req->process); r = req->process(req, link, req->userdata); if (r < 0) { - request_detach(manager, req); + request_detach(req); if (link) { link_enter_failed(link); @@ -261,7 +259,7 @@ int manager_process_requests(Manager *manager) { /* 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. */ - request_detach(manager, req); + request_detach(req); if (manager->request_queued) break; /* New request is queued. Exit from the loop. */ diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h index e911fdd33a..bdedc77537 100644 --- a/src/network/networkd-queue.h +++ b/src/network/networkd-queue.h @@ -88,7 +88,7 @@ Request *request_ref(Request *req); Request *request_unref(Request *req); DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_unref); -void request_detach(Manager *manager, Request *req); +void request_detach(Request *req); int netdev_queue_request( NetDev *netdev, diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 48b8af2f06..54bf107d02 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -1317,26 +1317,29 @@ int link_request_static_routes(Link *link, bool only_ipv4) { } void route_cancel_request(Route *route, Link *link) { - Request req; + Request *req; assert(route); link = route->link ?: link; assert(link); + assert(link->manager); if (!route_is_requesting(route)) return; - req = (Request) { - .link = link, - .type = REQUEST_TYPE_ROUTE, - .userdata = route, - .hash_func = (hash_func_t) route_hash_func, - .compare_func = (compare_func_t) route_compare_func, - }; - - request_detach(link->manager, &req); + req = ordered_set_get(link->manager->request_queue, + &(Request) { + .link = link, + .type = REQUEST_TYPE_ROUTE, + .userdata = route, + .hash_func = (hash_func_t) route_hash_func, + .compare_func = (compare_func_t) route_compare_func, + }); + + if (req) + request_detach(req); route_cancel_requesting(route); } -- 2.25.1