#include <sys/types.h>
#include <sys/stat.h>
#include <yaz/log.h>
+#include <yaz/nmem.h>
-#include "pazpar2.h"
+#include "ppmutex.h"
+#include "session.h"
#include "host.h"
+#include "pazpar2_config.h"
#include "settings.h"
#include "http.h"
#include "zeerex.h"
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)
}
// 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;
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;
+ pazpar2_mutex_create(&host->mutex, "host");
+
+ yaz_cond_create(&host->cond_ready);
+
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)
{
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;
}
{
struct database *db = service->databases;
for (; db; db = db->next)
- resolve_database(db);
+ resolve_database(service, db);
}
-static struct database *load_database(const char *id,
- struct conf_service *service)
+struct database *new_database(const char *id, NMEM nmem)
{
- xmlDoc *doc = 0;
- struct zr_explain *explain = 0;
struct database *db;
char hostport[256];
char *dbname;
struct setting *idset;
- if (service->targetprofiles
- && (doc = get_explain_xml(service->targetprofiles, id)))
- {
- explain = zr_read_xml(service->nmem, xmlDocGetRootElement(doc));
- if (!explain)
- return 0;
- }
-
if (strlen(id) > 255)
return 0;
strcpy(hostport, id);
*(dbname++) = '\0';
else
dbname = "";
- db = nmem_malloc(service->nmem, sizeof(*db));
+ db = nmem_malloc(nmem, sizeof(*db));
memset(db, 0, sizeof(*db));
db->host = 0;
- db->url = nmem_strdup(service->nmem, id);
- db->databases = nmem_malloc(service->nmem, 2 * sizeof(char *));
- db->databases[0] = nmem_strdup(service->nmem, dbname);
+ db->url = nmem_strdup(nmem, id);
+ db->databases = nmem_malloc(nmem, 2 * sizeof(char *));
+ db->databases[0] = nmem_strdup(nmem, dbname);
db->databases[1] = 0;
db->errors = 0;
- db->explain = explain;
+ db->explain = 0;
- db->num_settings = settings_num(service);
- db->settings = nmem_malloc(service->nmem, sizeof(struct settings*) *
+ db->num_settings = PZ_MAX_EOF;
+ db->settings = nmem_malloc(nmem, sizeof(struct settings*) *
db->num_settings);
memset(db->settings, 0, sizeof(struct settings*) * db->num_settings);
- idset = nmem_malloc(service->nmem, sizeof(*idset));
+ idset = nmem_malloc(nmem, sizeof(*idset));
idset->precedence = 0;
idset->name = "pz:id";
idset->target = idset->value = db->url;
idset->next = 0;
db->settings[PZ_ID] = idset;
+ db->next = 0;
+
+ return db;
+}
+static struct database *load_database(const char *id,
+ struct conf_service *service)
+{
+ struct database *db;
+ struct zr_explain *explain = 0;
+ xmlDoc *doc = 0;
+
+ if (service->targetprofiles
+ && (doc = get_explain_xml(service->targetprofiles, id)))
+ {
+ explain = zr_read_xml(service->nmem, xmlDocGetRootElement(doc));
+ if (!explain)
+ return 0;
+ }
+ db = new_database(id, service->nmem);
+ db->explain = explain;
db->next = service->databases;
service->databases = db;
return i;
}
+database_hosts_t database_hosts_create(void)
+{
+ database_hosts_t p = xmalloc(sizeof(*p));
+ p->hosts = 0;
+ p->mutex = 0;
+ pazpar2_mutex_create(&p->mutex, "database");
+ return p;
+}
+
+void database_hosts_destroy(database_hosts_t *pp)
+{
+ if (*pp)
+ {
+ struct host *p = (*pp)->hosts;
+ while (p)
+ {
+ struct host *p_next = p->next;
+ yaz_mutex_destroy(&p->mutex);
+ yaz_cond_destroy(&p->cond_ready);
+ xfree(p->ipport);
+ xfree(p->hostport);
+ xfree(p);
+ p = p_next;
+ }
+ yaz_mutex_destroy(&(*pp)->mutex);
+ xfree(*pp);
+ }
+}
+
/*
* Local variables:
* c-basic-offset: 4