This is an automated email from the git hooks/post-receive script.

git pushed a commit to reference refs/pull/125/head
in repository enlightenment.

View the commit online.

commit 5a7cd0eb20fa7bede855a70b83ba68a8a767e617
Author: [email protected] <[email protected]>
AuthorDate: Mon Mar 9 21:29:30 2026 -0600

    fix(networkmanager): prevent recursive popup refresh storm and hash race
    
    - Add saved_conn_pending counter to batch GetSettings replies
    - Only call enm_mod_aps_changed() once all replies arrive
    - Skip re-fetch if already in flight (guard in _enm_popup_update)
    - Use swap pattern for hash replacement to avoid NULL window
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 src/modules/networkmanager/e_mod_main.c       |  6 ++++--
 src/modules/networkmanager/e_networkmanager.c | 27 ++++++++++++++++++++-------
 src/modules/networkmanager/e_networkmanager.h |  1 +
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/src/modules/networkmanager/e_mod_main.c b/src/modules/networkmanager/e_mod_main.c
index dc0031faf..36c85b41e 100644
--- a/src/modules/networkmanager/e_mod_main.c
+++ b/src/modules/networkmanager/e_mod_main.c
@@ -314,8 +314,10 @@ _enm_popup_update(struct NM_Manager *nm, E_NM_Instance *inst)
 
    /* Refresh saved connections for forget button visibility.
     * This is async — the hash populates as D-Bus replies arrive,
-    * then enm_mod_aps_changed() triggers a popup re-render. */
-   enm_saved_connections_get(nm);
+    * then enm_mod_aps_changed() triggers a popup re-render.
+    * Skip if a fetch is already in flight to avoid recursive storms. */
+   if (nm->saved_conn_pending == 0)
+     enm_saved_connections_get(nm);
 
    e_widget_ilist_freeze(list);
    e_widget_ilist_clear(list);
diff --git a/src/modules/networkmanager/e_networkmanager.c b/src/modules/networkmanager/e_networkmanager.c
index 84fa76ba5..3ffbe6a18 100644
--- a/src/modules/networkmanager/e_networkmanager.c
+++ b/src/modules/networkmanager/e_networkmanager.c
@@ -1134,9 +1134,6 @@ _saved_conn_settings_cb(void *data, const Eldbus_Message *msg,
                        eina_hash_del_by_key(ctx->nm->saved_connections, ssid_str);
                        eina_hash_add(ctx->nm->saved_connections, ssid_str,
                                      eina_stringshare_add(ctx->path));
-
-                       /* Trigger popup refresh so forget buttons appear */
-                       enm_mod_aps_changed(ctx->nm);
                     }
                   goto done;
                }
@@ -1147,6 +1144,11 @@ done:
    eldbus_proxy_unref(ctx->proxy);
    eldbus_object_unref(ctx->obj);
    eina_stringshare_del(ctx->path);
+   /* Refresh popup once all GetSettings replies have arrived */
+   if (ctx->nm->saved_conn_pending > 0)
+     ctx->nm->saved_conn_pending--;
+   if (ctx->nm->saved_conn_pending == 0)
+     enm_mod_aps_changed(ctx->nm);
    free(ctx);
 }
 
@@ -1163,6 +1165,8 @@ _saved_conn_list_cb(void *data, const Eldbus_Message *msg,
    if (!eldbus_message_arguments_get(msg, "ao", &conn_array))
      return;
 
+   nm->saved_conn_pending = 0;
+
    while (eldbus_message_iter_get_and_next(conn_array, 'o', &conn_path))
      {
         struct _Saved_Conn_Ctx *ctx;
@@ -1175,10 +1179,15 @@ _saved_conn_list_cb(void *data, const Eldbus_Message *msg,
         ctx->obj = eldbus_object_get(conn, NM_BUS_NAME, conn_path);
         ctx->proxy = eldbus_proxy_get(ctx->obj, NM_IFACE_SCONN);
 
+        nm->saved_conn_pending++;
         eldbus_proxy_call(ctx->proxy, "GetSettings",
                           _saved_conn_settings_cb, ctx, -1, "");
         /* ctx, proxy, and obj are freed/unref'd inside _saved_conn_settings_cb */
      }
+
+   /* If no connections found, trigger refresh immediately */
+   if (nm->saved_conn_pending == 0)
+     enm_mod_aps_changed(nm);
 }
 
 static void
@@ -1195,10 +1204,14 @@ enm_saved_connections_get(struct NM_Manager *nm)
 
    EINA_SAFETY_ON_NULL_RETURN(nm);
 
-   if (nm->saved_connections)
-     eina_hash_free(nm->saved_connections);
-   nm->saved_connections = eina_hash_string_superfast_new(
-                              _saved_connections_free_cb);
+   {
+      /* Swap pattern: assign new hash before freeing old to avoid a window
+       * where saved_connections is NULL (in-flight callbacks check it) */
+      Eina_Hash *old = nm->saved_connections;
+      nm->saved_connections = eina_hash_string_superfast_new(
+                                 _saved_connections_free_cb);
+      if (old) eina_hash_free(old);
+   }
 
    settings_obj = eldbus_object_get(conn, NM_BUS_NAME, NM_SETTINGS_PATH);
    settings_proxy = eldbus_proxy_get(settings_obj, NM_IFACE_SETTINGS);
diff --git a/src/modules/networkmanager/e_networkmanager.h b/src/modules/networkmanager/e_networkmanager.h
index 553ca6db9..7cb4b69fa 100644
--- a/src/modules/networkmanager/e_networkmanager.h
+++ b/src/modules/networkmanager/e_networkmanager.h
@@ -121,6 +121,7 @@ struct NM_Manager
 
    /* Saved WiFi connections: SSID (string) -> connection D-Bus path (stringshare) */
    Eina_Hash    *saved_connections;
+   int           saved_conn_pending; /* outstanding GetSettings calls */
 };
 
 /* Ecore Events */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to