client_destroy destroys ZOOM_resultset (bug #3489).
[pazpar2-moved-to-github.git] / src / pazpar2_config.c
index fb62e99..ec87caf 100644 (file)
@@ -38,6 +38,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#include "ppmutex.h"
+#include "incref.h"
 #include "pazpar2_config.h"
 #include "settings.h"
 #include "eventl.h"
@@ -47,8 +49,11 @@ struct conf_config
 {
     NMEM nmem; /* for conf_config and servers memory */
     struct conf_server *servers;
+    
     int no_threads;
     WRBUF confdir;
+    iochan_man_t iochan_man;
+    database_hosts_t database_hosts;
 };
 
 
@@ -111,6 +116,7 @@ static struct conf_service *service_init(struct conf_server *server,
     NMEM nmem = nmem_create();
 
     service = nmem_malloc(nmem, sizeof(struct conf_service));
+    service->mutex = 0;
     service->ref_count = 1;
     service->nmem = nmem;
     service->next = 0;
@@ -238,13 +244,12 @@ void service_destroy(struct conf_service *service)
 {
     if (service)
     {
-        assert(service->ref_count > 0);
-        service->ref_count--;
-        if (service->ref_count == 0)
+        if (!pazpar2_decref(&service->ref_count, service->mutex))
         {
             pp2_charset_destroy(service->relevance_pct);
             pp2_charset_destroy(service->sort_pct);
             pp2_charset_destroy(service->mergekey_pct);
+            yaz_mutex_destroy(&service->mutex);
             nmem_destroy(service->nmem);
         }
     }
@@ -252,7 +257,9 @@ void service_destroy(struct conf_service *service)
 
 void service_incref(struct conf_service *service)
 {
-    service->ref_count++;
+    yaz_log(YLOG_LOG, "service_incref. p=%p cnt=%d", service,
+            service->ref_count);
+    pazpar2_incref(&service->ref_count, service->mutex);
 }
 
 static int parse_metadata(struct conf_service *service, xmlNode *n,
@@ -690,6 +697,8 @@ struct conf_service *service_create(struct conf_server *server,
     {
         inherit_server_settings(service);
         resolve_databases(service);
+        assert(service->mutex == 0);
+        pazpar2_mutex_create(&service->mutex, "conf");
     }
     return service;
 }
@@ -706,7 +715,6 @@ static struct conf_server *server_create(struct conf_config *config,
     server->proxy_host = 0;
     server->proxy_port = 0;
     server->myurl = 0;
-    server->proxy_addr = 0;
     server->service = 0;
     server->config = config;
     server->next = 0;
@@ -714,6 +722,9 @@ static struct conf_server *server_create(struct conf_config *config,
     server->sort_pct = 0;
     server->mergekey_pct = 0;
     server->server_settings = 0;
+    server->http_server = 0;
+    server->iochan_man = 0;
+    server->database_hosts = 0;
 
     if (server_id)
     {
@@ -829,9 +840,8 @@ static struct conf_server *server_create(struct conf_config *config,
     return server;
 }
 
-WRBUF conf_get_fname(struct conf_service *service, const char *fname)
+WRBUF conf_get_fname(struct conf_config *config, const char *fname)
 {
-    struct conf_config *config = service->server->config;
     WRBUF w = wrbuf_alloc();
 
     conf_dir_path(config, w, fname);
@@ -881,10 +891,12 @@ struct conf_service *locate_service(struct conf_server *server,
     struct conf_service *s = server->service;
     for (; s; s = s->next)
         if (s->id && service_id && 0 == strcmp(s->id, service_id))
-            return s;
+            break;
         else if (!s->id && !service_id)
-            return s;
-    return 0;
+            break;
+    if (s)
+        service_incref(s);
+    return s;
 }
 
 
@@ -909,7 +921,7 @@ static int parse_config(struct conf_config *config, xmlNode *root)
             xmlChar *number = xmlGetProp(n, (xmlChar *) "number");
             if (number)
             {
-                config->no_threads = atoi(number);
+                config->no_threads = atoi((const char *) number);
                 xmlFree(number);
             }
         }
@@ -949,6 +961,7 @@ struct conf_config *config_create(const char *fname, int verbose)
     config->nmem = nmem;
     config->servers = 0;
     config->no_threads = 0;
+    config->iochan_man = 0;
 
     config->confdir = wrbuf_alloc();
     if ((p = strrchr(fname, 
@@ -1002,6 +1015,8 @@ void server_destroy(struct conf_server *server)
     pp2_charset_destroy(server->relevance_pct);
     pp2_charset_destroy(server->sort_pct);
     pp2_charset_destroy(server->mergekey_pct);
+    yaz_log(YLOG_LOG, "server_destroy server=%p", server);
+    http_server_destroy(server->http_server);
 }
 
 void config_destroy(struct conf_config *config)
@@ -1009,12 +1024,15 @@ void config_destroy(struct conf_config *config)
     if (config)
     {
         struct conf_server *server = config->servers;
+        iochan_man_destroy(&config->iochan_man);    
         while (server)
         {
             struct conf_server *s_next = server->next;
             server_destroy(server);
             server = s_next;
         }
+        database_hosts_destroy(&config->database_hosts);
+
         wrbuf_destroy(config->confdir);
         nmem_destroy(config->nmem);
     }
@@ -1027,26 +1045,40 @@ void config_stop_listeners(struct conf_config *conf)
         http_close_server(ser);
 }
 
-void config_start_databases(struct conf_config *conf)
+void config_process_events(struct conf_config *conf)
 {
     struct conf_server *ser;
+    
+    conf->database_hosts = database_hosts_create();
     for (ser = conf->servers; ser; ser = ser->next)
     {
         struct conf_service *s = ser->service;
+
+        ser->database_hosts = conf->database_hosts;
+
         for (;s ; s = s->next)
+        {
             resolve_databases(s);
+            assert(s->mutex == 0);
+            pazpar2_mutex_create(&s->mutex, "service");
+        }
+        http_mutex_init(ser);
     }
+    iochan_man_events(conf->iochan_man);    
 }
 
 int config_start_listeners(struct conf_config *conf,
                            const char *listener_override)
 {
     struct conf_server *ser;
-    pazpar2_chan_man_start(conf->no_threads);
+
+    conf->iochan_man = iochan_man_create(conf->no_threads);
     for (ser = conf->servers; ser; ser = ser->next)
     {
         WRBUF w = wrbuf_alloc();
         int r;
+
+        ser->iochan_man = conf->iochan_man;
         if (listener_override)
         {
             wrbuf_puts(w, listener_override);