network/queue: do not check if a request is ready multiple times in a single event
Some checks are slightly heavy, and there may be huge number of interfaces. So, prcessing whole queue multiple times in a single event may decrease the performance. Let's process the queued requests once per event.
This commit is contained in:
@@ -215,52 +215,42 @@ int link_queue_request_full(
|
||||
}
|
||||
|
||||
int manager_process_requests(Manager *manager) {
|
||||
Request *req;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
|
||||
for (;;) {
|
||||
bool processed = false;
|
||||
Request *req;
|
||||
ORDERED_SET_FOREACH(req, manager->request_queue) {
|
||||
_cleanup_(link_unrefp) Link *link = link_ref(req->link);
|
||||
|
||||
ORDERED_SET_FOREACH(req, manager->request_queue) {
|
||||
_cleanup_(link_unrefp) Link *link = link_ref(req->link);
|
||||
assert(req->process);
|
||||
|
||||
assert(req->process);
|
||||
if (req->waiting_reply)
|
||||
continue; /* Waiting for netlink reply. */
|
||||
|
||||
if (req->waiting_reply)
|
||||
continue; /* Waiting for netlink reply. */
|
||||
/* Typically, requests send netlink message asynchronously. If there are many requests
|
||||
* queued, then this event may make reply callback queue in sd-netlink full. */
|
||||
if (netlink_get_reply_callback_count(manager->rtnl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
|
||||
netlink_get_reply_callback_count(manager->genl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
|
||||
fw_ctx_get_reply_callback_count(manager->fw_ctx) >= REPLY_CALLBACK_COUNT_THRESHOLD)
|
||||
return 0;
|
||||
|
||||
/* Typically, requests send netlink message asynchronously. If there are many requests
|
||||
* queued, then this event may make reply callback queue in sd-netlink full. */
|
||||
if (netlink_get_reply_callback_count(manager->rtnl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
|
||||
netlink_get_reply_callback_count(manager->genl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
|
||||
fw_ctx_get_reply_callback_count(manager->fw_ctx) >= REPLY_CALLBACK_COUNT_THRESHOLD)
|
||||
return 0;
|
||||
r = req->process(req, link, req->userdata);
|
||||
if (r == 0)
|
||||
continue; /* The request is not ready. */
|
||||
|
||||
r = req->process(req, link, req->userdata);
|
||||
if (r == 0)
|
||||
continue;
|
||||
/* 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);
|
||||
|
||||
processed = true;
|
||||
|
||||
/* 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);
|
||||
/* link_enter_failed() may remove multiple requests,
|
||||
* hence we need to exit from the loop. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* When at least one request is processed, then another request may be ready now. */
|
||||
if (!processed)
|
||||
if (r < 0 && link) {
|
||||
link_enter_failed(link);
|
||||
/* link_enter_failed() may remove multiple requests,
|
||||
* hence we need to exit from the loop. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user