This is an automated email from the ASF dual-hosted git repository.

jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit 2d949fa7c57b1a836f1217d8093787a63c9c04a1
Author: Nightt <[email protected]>
AuthorDate: Mon May 25 10:46:59 2026 +0800

    system/settings: Avoid recursive save locking
    
    Fix #3105 by making the immediate save path write pending settings while 
the caller still owns g_settings.mtx instead of calling the timer callback, 
which locks the same mutex again.
    
    The cached-save timer callback still takes the mutex before using the same 
locked helper, so asynchronous saves keep their existing synchronization while 
non-cached saves no longer depend on a recursive mutex.
    
    Signed-off-by: Nightt <[email protected]>
---
 system/settings/settings.c | 62 +++++++++++++++++++++++++++-------------------
 1 file changed, 36 insertions(+), 26 deletions(-)

diff --git a/system/settings/settings.c b/system/settings/settings.c
index 105c093dd..c478e96f8 100644
--- a/system/settings/settings.c
+++ b/system/settings/settings.c
@@ -82,7 +82,10 @@ static int      set_ip(FAR setting_t *setting, FAR struct 
in_addr *ip);
 static int      load(void);
 static void     save(void);
 static void     signotify(void);
+static void     dump_cache_locked(FAR bool *wrpend);
+#ifdef CONFIG_SYSTEM_SETTINGS_CACHED_SAVES
 static void     dump_cache(union sigval ptr);
+#endif
 
 /****************************************************************************
  * Private Data
@@ -623,12 +626,7 @@ static void save(void)
 #ifdef CONFIG_SYSTEM_SETTINGS_CACHED_SAVES
   timer_settime(g_settings.timerid, 0, &g_settings.trigger, NULL);
 #else
-  union sigval value =
-  {
-    .sival_ptr = &g_settings.wrpend,
-  };
-
-  dump_cache(value);
+  dump_cache_locked(&g_settings.wrpend);
 #endif
 }
 
@@ -662,51 +660,63 @@ static void signotify(void)
 }
 
 /****************************************************************************
- * Name: dump_cache
+ * Name: dump_cache_locked
  *
  * Description:
- *    Writes out the cached data to the appropriate storage
+ *    Writes out the cached data to the appropriate storage.  The caller
+ *    must hold g_settings.mtx.
  *
  * Input Parameters:
- *    value            - parameter passed if called from a timer signal
+ *    wrpend           - pending write flag to clear after dumping
  *
  * Returned Value:
  *   None
  *
  ****************************************************************************/
 
-static void dump_cache(union sigval ptr)
+static void dump_cache_locked(FAR bool *wrpend)
 {
-  int ret = OK;
-  FAR bool *wrpend = (bool *)ptr.sival_ptr;
-
   int i;
 
-  ret = pthread_mutex_lock(&g_settings.mtx);
-  assert(ret >= 0);
-
   for (i = 0; i < CONFIG_SYSTEM_SETTINGS_MAX_STORAGES; i++)
     {
       if ((g_settings.store[i].file[0] != '\0') &&
            g_settings.store[i].save_fn)
         {
-          ret = g_settings.store[i].save_fn(g_settings.store[i].file);
-#if 0
-          if (ret < 0)
-            {
-              /* What to do? We can't return anything from a void function.
-               *
-               * MIGHT BE A FUTURE REVISIT NEEDED
-               */
-            }
-#endif
+          (void)g_settings.store[i].save_fn(g_settings.store[i].file);
         }
     }
 
   *wrpend = false;
+}
 
+#ifdef CONFIG_SYSTEM_SETTINGS_CACHED_SAVES
+/****************************************************************************
+ * Name: dump_cache
+ *
+ * Description:
+ *    Writes out the cached data to the appropriate storage
+ *
+ * Input Parameters:
+ *    value            - parameter passed if called from a timer signal
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void dump_cache(union sigval ptr)
+{
+  FAR bool *wrpend = (FAR bool *)ptr.sival_ptr;
+  int ret;
+
+  ret = pthread_mutex_lock(&g_settings.mtx);
+  assert(ret >= 0);
+
+  dump_cache_locked(wrpend);
   pthread_mutex_unlock(&g_settings.mtx);
 }
+#endif
 
 /****************************************************************************
  * Name: sanity_check

Reply via email to