]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/queue: detach request from queue when netlink reply received 28574/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 8 Jul 2023 22:06:24 +0000 (07:06 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 29 Jul 2023 14:27:21 +0000 (23:27 +0900)
Then, we can find and use the Request object after sending netlink
message.

Preparation for later commits.

src/network/networkd-queue.c
src/network/networkd-queue.h

index d5193538d899075378d36740696c2f94663385f5..90caefbc72c82143c467feaf5a2179ee75772930 100644 (file)
@@ -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;
 }
 
index 6db0005e619054521dae3d574833346ef69908c7..e58d1be66f5542ea12a96fd3e44d4d8bd6033142 100644 (file)
@@ -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);