Fix session_nmem may be used by multiple threads PAZ-962
[pazpar2-moved-to-github.git] / src / session.c
index 2823399..69d05ae 100644 (file)
@@ -883,7 +883,7 @@ void session_init_databases(struct session *se)
 // Probably session_init_databases_fun should be refactored instead of
 // called here.
 static struct session_database *load_session_database(struct session *se,
-                                                      char *id)
+                                                      const char *id)
 {
     struct database *db = new_database_inherit_settings(id, se->session_nmem, se->service->settings);
     session_init_databases_fun((void*) se, db);
@@ -894,7 +894,7 @@ static struct session_database *load_session_database(struct session *se,
 
 // Find an existing session database. If not found, load it
 static struct session_database *find_session_database(struct session *se,
-                                                      char *id)
+                                                      const char *id)
 {
     struct session_database *sdb;
 
@@ -905,38 +905,39 @@ static struct session_database *find_session_database(struct session *se,
 }
 
 // Apply a session override to a database
-void session_apply_setting(struct session *se, char *dbname, char *name,
-                           char *value)
+void session_apply_setting(struct session *se, const char *dbname,
+                           const char *name, const char *value)
 {
-    struct session_database *sdb = find_session_database(se, dbname);
-    struct conf_service *service = se->service;
-    struct setting *s;
-    int offset = settings_create_offset(service, name);
-
-    expand_settings_array(&sdb->settings, &sdb->num_settings, offset,
-                          se->session_nmem);
-
-    // Force later recompute of settings-driven data structures
-    // (happens when a search starts and client connections are prepared)
-    if (offset == PZ_XSLT)
-        sdb->map = 0;
-
-    se->settings_modified = 1;
-    for (s = sdb->settings[offset]; s; s = s->next)
-        if (!strcmp(s->name, name) &&
-            dbname && s->target && !strcmp(dbname, s->target))
+    session_enter(se, "session_apply_setting");
+    {
+        struct session_database *sdb = find_session_database(se, dbname);
+        struct conf_service *service = se->service;
+        struct setting *s;
+        int offset = settings_create_offset(service, name);
+
+        expand_settings_array(&sdb->settings, &sdb->num_settings, offset,
+                              se->session_nmem);
+        // Force later recompute of settings-driven data structures
+        // (happens when a search starts and client connections are prepared)
+        if (offset == PZ_XSLT)
+            sdb->map = 0;
+        se->settings_modified = 1;
+        for (s = sdb->settings[offset]; s; s = s->next)
+            if (!strcmp(s->name, name) &&
+                dbname && s->target && !strcmp(dbname, s->target))
+                break;
+        if (!s)
         {
-            s->value = value;
-            return;
+            s = nmem_malloc(se->session_nmem, sizeof(*s));
+            s->precedence = 0;
+            s->target = nmem_strdup(se->session_nmem, dbname);
+            s->name = nmem_strdup(se->session_nmem, name);
+            s->next = sdb->settings[offset];
+            sdb->settings[offset] = s;
         }
-    s = nmem_malloc(se->session_nmem, sizeof(*s));
-    s->precedence = 0;
-    s->target = dbname;
-    s->name = name;
-    s->value = value;
-    s->next = sdb->settings[offset];
-    sdb->settings[offset] = s;
-
+        s->value = nmem_strdup(se->session_nmem, value);
+    }
+    session_leave(se, "session_apply_setting");
 }
 
 void session_destroy(struct session *se)