Merge branch 'master' into paz-927
[pazpar2-moved-to-github.git] / src / session.c
index 2823399..b0d1bcf 100644 (file)
@@ -508,7 +508,6 @@ static void select_targets_callback(struct session *se,
         l->next = se->clients_cached;
         se->clients_cached = l;
     }
-    /* set session always. If may be 0 if client is not active */
     client_set_session(cl, se);
 
     l = xmalloc(sizeof(*l));
@@ -557,6 +556,7 @@ static void session_remove_cached_clients(struct session *se)
         client_lock(l->client);
         client_set_session(l->client, 0);
         client_set_database(l->client, 0);
+        client_mark_dead(l->client);
         client_unlock(l->client);
         client_destroy(l->client);
         xfree(l);
@@ -746,17 +746,21 @@ enum pazpar2_error_code session_search(struct session *se,
     int no_working = 0;
     int no_failed_query = 0;
     int no_failed_limit = 0;
-    struct client_list *l, *l0;
-
-    session_alert_watch(se, SESSION_WATCH_SHOW);
-    session_alert_watch(se, SESSION_WATCH_BYTARGET);
-    session_alert_watch(se, SESSION_WATCH_TERMLIST);
-    session_alert_watch(se, SESSION_WATCH_SHOW_PREF);
+    struct client_list *l;
 
     session_log(se, YLOG_DEBUG, "Search");
 
     *addinfo = 0;
 
+    session_enter(se, "session_search0");
+    if (se->clients_starting)
+    {
+        session_leave(se, "session_search0");
+        return PAZPAR2_NO_ERROR;
+    }
+    se->clients_starting = 1;
+    session_leave(se, "session_search0");
+
     if (se->settings_modified) {
         session_remove_cached_clients(se);
     }
@@ -784,6 +788,7 @@ enum pazpar2_error_code session_search(struct session *se,
     if (!live_channels)
     {
         session_leave(se, "session_search");
+        se->clients_starting = 0;
         return PAZPAR2_NO_TARGETS;
     }
 
@@ -793,14 +798,18 @@ enum pazpar2_error_code session_search(struct session *se,
     {
         *addinfo = "limit";
         session_leave(se, "session_search");
+        se->clients_starting = 0;
         return PAZPAR2_MALFORMED_PARAMETER_VALUE;
     }
 
-    l0 = se->clients_active;
-    se->clients_active = 0;
     session_leave(se, "session_search");
 
-    for (l = l0; l; l = l->next)
+    session_alert_watch(se, SESSION_WATCH_SHOW);
+    session_alert_watch(se, SESSION_WATCH_BYTARGET);
+    session_alert_watch(se, SESSION_WATCH_TERMLIST);
+    session_alert_watch(se, SESSION_WATCH_SHOW_PREF);
+
+    for (l = se->clients_active; l; l = l->next)
     {
         int parse_ret;
         struct client *cl = l->client;
@@ -823,8 +832,9 @@ enum pazpar2_error_code session_search(struct session *se,
             no_working++;
         }
     }
-    session_reset_active_clients(se, l0);
-
+    session_enter(se, "session_search2");
+    se->clients_starting = 0;
+    session_leave(se, "session_search2");
     if (no_working == 0)
     {
         if (no_failed_query > 0)
@@ -883,7 +893,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 +904,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 +915,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)
@@ -1003,6 +1014,7 @@ struct session *new_session(NMEM nmem, struct conf_service *service,
     session->facet_limits = 0;
     session->mergekey = 0;
     session->rank = 0;
+    session->clients_starting = 0;
 
     for (i = 0; i <= SESSION_WATCH_MAX; i++)
     {