Fix session_nmem may be used by multiple threads PAZ-962
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 9 Sep 2014 10:40:54 +0000 (12:40 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 9 Sep 2014 10:40:54 +0000 (12:40 +0200)
src/http_command.c
src/session.c
src/session.h

index f4cc792..309a617 100644 (file)
@@ -401,6 +401,7 @@ static int process_settings(struct session *se, struct http_request *rq,
                             struct http_response *rs)
 {
     struct http_argument *a;
+    NMEM nmem = nmem_create();
 
     for (a = rq->arguments; a; a = a->next)
         if (strchr(a->name, '['))
@@ -411,17 +412,18 @@ static int process_settings(struct session *se, struct http_request *rq,
             char *setting;
 
             // Nmem_strsplit *rules*!!!
-            nmem_strsplit(se->session_nmem, "[]", a->name, &res, &num);
+            nmem_strsplit(nmem, "[]", a->name, &res, &num);
             if (num != 2)
             {
                 error(rs, PAZPAR2_MALFORMED_SETTING, a->name);
+                nmem_destroy(nmem);
                 return -1;
             }
             setting = res[0];
             dbname = res[1];
-            session_apply_setting(se, dbname, setting,
-                    nmem_strdup(se->session_nmem, a->value));
+            session_apply_setting(se, dbname, setting, a->value);
         }
+    nmem_destroy(nmem);
     return 0;
 }
 
@@ -507,9 +509,7 @@ static void apply_local_setting(void *client_data,
 {
     struct session *se =  (struct session *) client_data;
 
-    session_apply_setting(se, nmem_strdup(se->session_nmem, set->target),
-                          nmem_strdup(se->session_nmem, set->name),
-                          nmem_strdup(se->session_nmem, set->value));
+    session_apply_setting(se, set->target, set->name, set->value);
 }
 
 static void cmd_settings(struct http_channel *c)
index 5cba1d6..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,8 +905,8 @@ 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)
 {
     session_enter(se, "session_apply_setting");
     {
@@ -930,12 +930,12 @@ void session_apply_setting(struct session *se, char *dbname, char *name,
         {
             s = nmem_malloc(se->session_nmem, sizeof(*s));
             s->precedence = 0;
-            s->target = dbname;
-            s->name = name;
+            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->value = value;
+        s->value = nmem_strdup(se->session_nmem, value);
     }
     session_leave(se, "session_apply_setting");
 }
index 32243de..8f61f9a 100644 (file)
@@ -182,7 +182,8 @@ void show_single_stop(struct session *s, struct record_cluster *rec);
 int session_set_watch(struct session *s, int what, session_watchfun fun, void *data, struct http_channel *c);
 int session_active_clients(struct session *s);
 int session_is_preferred_clients_ready(struct session *s);
-void session_apply_setting(struct session *se, char *dbname, char *setting, char *value);
+void session_apply_setting(struct session *se, const char *dbname,
+                           const char *setting, const char *value);
 const char *session_setting_oneval(struct session_database *db, int offset);
 
 int ingest_record(struct client *cl, const char *rec, int record_no, NMEM nmem);