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);
}
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);
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);
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);
return r;
request_ref(req);
+ req->waiting_reply = true;
return 0;
}