Protect struct reclist
[pazpar2-moved-to-github.git] / src / database.c
index c2fb3b1..6f1599a 100644 (file)
@@ -63,7 +63,11 @@ struct database_criterion {
     struct database_criterion *next;
 };
 
-static struct host *hosts = 0;  /* thread pr */
+
+struct database_hosts {
+    struct host *hosts;
+    YAZ_MUTEX mutex;
+};
 
 static xmlDoc *get_explain_xml(struct conf_targetprofiles *targetprofiles,
                                const char *id)
@@ -87,7 +91,7 @@ static xmlDoc *get_explain_xml(struct conf_targetprofiles *targetprofiles,
 }
 
 // Create a new host structure for hostport
-static struct host *create_host(const char *hostport)
+static struct host *create_host(const char *hostport, iochan_man_t iochan_man)
 {
     struct host *host;
 
@@ -95,28 +99,41 @@ static struct host *create_host(const char *hostport)
     host->hostport = xstrdup(hostport);
     host->connections = 0;
     host->ipport = 0;
+    host->mutex = 0;
 
-    if (host_getaddrinfo(host))
+    if (host_getaddrinfo(host, iochan_man))
     {
         xfree(host->hostport);
         xfree(host);
         return 0;
     }
-    host->next = hosts;
-    hosts = host;
+    yaz_mutex_create(&host->mutex);
+
     return host;
 }
 
-static struct host *find_host(const char *hostport)
+static struct host *find_host(database_hosts_t hosts,
+                              const char *hostport, iochan_man_t iochan_man)
 {
     struct host *p;
-    for (p = hosts; p; p = p->next)
+    yaz_mutex_enter(hosts->mutex);
+    for (p = hosts->hosts; p; p = p->next)
         if (!strcmp(p->hostport, hostport))
-            return p;
-    return create_host(hostport);
+            break;
+    if (!p)
+    {
+        p = create_host(hostport, iochan_man);
+        if (p)
+        {
+            p->next = hosts->hosts;
+            hosts->hosts = p;
+        }
+    }
+    yaz_mutex_leave(hosts->mutex);
+    return p;
 }
 
-int resolve_database(struct database *db)
+int resolve_database(struct conf_service *service, struct database *db)
 {
     if (db->host == 0)
     {
@@ -126,7 +143,8 @@ int resolve_database(struct database *db)
         strcpy(hostport, db->url);
         if ((p = strchr(hostport, '/')))
             *p = '\0';
-        if (!(host = find_host(hostport)))
+        if (!(host = find_host(service->server->database_hosts,
+                               hostport, service->server->iochan_man)))
             return -1;
         db->host = host;
     }
@@ -137,7 +155,7 @@ void resolve_databases(struct conf_service *service)
 {
     struct database *db = service->databases;
     for (; db; db = db->next)
-        resolve_database(db);
+        resolve_database(service, db);
 }
 
 struct database *new_database(const char *id, NMEM nmem)
@@ -385,6 +403,15 @@ int predef_grep_databases(void *context, struct conf_service *service,
     return i;
 }
 
+database_hosts_t database_hosts_create(void)
+{
+    database_hosts_t p = xmalloc(sizeof(*p));
+    p->hosts = 0;
+    p->mutex = 0;
+    yaz_mutex_create(&p->mutex);
+    return p;
+}
+
 /*
  * Local variables:
  * c-basic-offset: 4