mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-08 19:40:34 +01:00
l3cfg: let l3cfg emit signal on idle handler for platform changes
Currently all NMDevice instance register to the platform change signals, then if a signal for their IP ifindex appears, they schedule a task on an idle handler. That is wasteful. NML3Cfg already gets a notification on an idle handler and can just re-emit it to the respective listeners. With this, there is only one subscriber to the platform signals (NMNetns) which then multiplexes the signals to the right NML3Cfg instances, and further.
This commit is contained in:
parent
000ad171e3
commit
7ff1beabdb
4 changed files with 40 additions and 2 deletions
|
|
@ -3014,6 +3014,7 @@ _dev_l3_cfg_notify_cb (NML3Cfg *l3cfg,
|
|||
case NM_L3_CONFIG_NOTIFY_TYPE_ACD_COMPLETED:
|
||||
_dev_l3_cfg_acd_maybe_comlete (self);
|
||||
return;
|
||||
case NM_L3_CONFIG_NOTIFY_TYPE_NOTIFY_PLATFORM_CHANGE_ON_IDLE:
|
||||
case NM_L3_CONFIG_NOTIFY_TYPE_ROUTES_TEMPORARY_NOT_AVAILABLE_EXPIRED:
|
||||
/* FIXME(l3cfg) */
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -620,8 +620,20 @@ _load_link (NML3Cfg *self, gboolean initial)
|
|||
void
|
||||
_nm_l3cfg_notify_platform_change_on_idle (NML3Cfg *self, guint32 obj_type_flags)
|
||||
{
|
||||
NML3ConfigNotifyPayload payload;
|
||||
|
||||
if (NM_FLAGS_ANY (obj_type_flags, nmp_object_type_to_flags (NMP_OBJECT_TYPE_LINK)))
|
||||
_load_link (self, FALSE);
|
||||
|
||||
payload = (NML3ConfigNotifyPayload) {
|
||||
.platform_change_on_idle = {
|
||||
.obj_type_flags = obj_type_flags,
|
||||
},
|
||||
};
|
||||
_l3cfg_emit_signal_notify (self,
|
||||
NM_L3_CONFIG_NOTIFY_TYPE_NOTIFY_PLATFORM_CHANGE_ON_IDLE,
|
||||
&payload);
|
||||
|
||||
if (NM_FLAGS_ANY (obj_type_flags, nmp_object_type_to_flags (NMP_OBJECT_TYPE_IP4_ROUTE)))
|
||||
_property_emit_notify (self, NM_L3CFG_PROPERTY_EMIT_TYPE_IP4_ROUTE);
|
||||
if (NM_FLAGS_ANY (obj_type_flags, nmp_object_type_to_flags (NMP_OBJECT_TYPE_IP6_ROUTE)))
|
||||
|
|
|
|||
|
|
@ -22,6 +22,13 @@ typedef enum {
|
|||
NM_L3_CONFIG_NOTIFY_TYPE_ROUTES_TEMPORARY_NOT_AVAILABLE_EXPIRED,
|
||||
NM_L3_CONFIG_NOTIFY_TYPE_ACD_FAILED,
|
||||
NM_L3_CONFIG_NOTIFY_TYPE_ACD_COMPLETED,
|
||||
|
||||
/* NML3Cfg hooks to the NMPlatform signals for link, addresses and routes.
|
||||
* It re-emits the signal on an idle handler. The purpose is for something
|
||||
* like NMDevice which is already subscribed to these signals, it can get the
|
||||
* notifications without also subscribing directly to the platform. */
|
||||
NM_L3_CONFIG_NOTIFY_TYPE_NOTIFY_PLATFORM_CHANGE_ON_IDLE,
|
||||
|
||||
_NM_L3_CONFIG_NOTIFY_TYPE_NUM,
|
||||
} NML3ConfigNotifyType;
|
||||
|
||||
|
|
@ -38,6 +45,10 @@ typedef struct {
|
|||
guint sources_len;
|
||||
const NML3ConfigNotifyPayloadAcdFailedSource *sources;
|
||||
} acd_failed;
|
||||
|
||||
struct {
|
||||
guint32 obj_type_flags;
|
||||
} platform_change_on_idle;
|
||||
};
|
||||
} NML3ConfigNotifyPayload;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "nm-netns.h"
|
||||
|
||||
#include "nm-glib-aux/nm-dedup-multi.h"
|
||||
#include "nm-glib-aux/nm-c-list.h"
|
||||
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
|
@ -175,14 +176,27 @@ _platform_signal_on_idle_cb (gpointer user_data)
|
|||
gs_unref_object NMNetns *self = g_object_ref (NM_NETNS (user_data));
|
||||
NMNetnsPrivate *priv = NM_NETNS_GET_PRIVATE (self);
|
||||
L3CfgData *l3cfg_data;
|
||||
CList work_list;
|
||||
|
||||
while ((l3cfg_data = c_list_first_entry (&priv->l3cfg_signal_pending_lst_head, L3CfgData, signal_pending_lst))) {
|
||||
priv->signal_pending_idle_id = 0;
|
||||
|
||||
/* we emit all queued signals together. However, we don't want to hook the
|
||||
* main loop for longer than the currently queued elements.
|
||||
*
|
||||
* If we catch more change events, they will be queued and processed by a future
|
||||
* idle handler.
|
||||
*
|
||||
* Hence, move the list to a temporary list. Isn't CList great? */
|
||||
|
||||
c_list_init (&work_list);
|
||||
c_list_splice (&work_list, &priv->l3cfg_signal_pending_lst_head);
|
||||
|
||||
while ((l3cfg_data = c_list_first_entry (&work_list, L3CfgData, signal_pending_lst))) {
|
||||
c_list_unlink (&l3cfg_data->signal_pending_lst);
|
||||
_nm_l3cfg_notify_platform_change_on_idle (l3cfg_data->l3cfg,
|
||||
nm_steal_int (&l3cfg_data->signal_pending_flag));
|
||||
}
|
||||
|
||||
priv->signal_pending_idle_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue