/* This file is part of Pazpar2.
- Copyright (C) 2006-2008 Index Data
+ Copyright (C) 2006-2009 Index Data
Pazpar2 is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
-#if HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef WIN32
-#include <winsock.h>
-typedef int socklen_t;
-#endif
-#if HAVE_NETDB_H
-#include <netdb.h>
-#endif
#include <signal.h>
-#include <ctype.h>
#include <assert.h>
#include <yaz/log.h>
struct connection {
IOCHAN iochan;
ZOOM_connection link;
- ZOOM_resultset resultset;
struct host *host;
struct client *client;
char *ibuf;
static struct connection *connection_freelist = 0;
+static int connection_connect(struct connection *con);
+
static int connection_is_idle(struct connection *co)
{
ZOOM_connection link = co->link;
if (co->state != Conn_Open || !link)
return 0;
+ if (!ZOOM_connection_is_idle(link))
+ return 0;
event = ZOOM_connection_peek_event(link);
- if (event == ZOOM_EVENT_NONE ||
- event == ZOOM_EVENT_END)
+ if (event == ZOOM_EVENT_NONE || event == ZOOM_EVENT_END)
return 1;
else
return 0;
return co->link;
}
-ZOOM_resultset connection_get_resultset(struct connection *co)
-{
- return co->resultset;
-}
-
-void connection_set_resultset(struct connection *co, ZOOM_resultset rs)
-{
- if (co->resultset)
- ZOOM_resultset_destroy(co->resultset);
- co->resultset = rs;
-}
-
static void remove_connection_from_host(struct connection *con)
{
struct connection **conp = &con->host->connections;
assert(*conp == 0);
}
-void connection_continue(struct connection *co)
-{
- yaz_log(YLOG_LOG, "connection_continue");
- iochan_setevent(co->iochan, EVENT_OUTPUT);
-}
-
// Close connection and recycle structure
void connection_destroy(struct connection *co)
{
ZOOM_connection_destroy(co->link);
iochan_destroy(co->iochan);
}
- if (co->resultset)
- ZOOM_resultset_destroy(co->resultset);
-
yaz_log(YLOG_DEBUG, "Connection destroy %s", co->host->hostport);
remove_connection_from_host(co);
new->zproxy = 0;
client_set_connection(cl, new);
new->link = 0;
- new->resultset = 0;
new->state = Conn_Resolving;
if (host->ipport)
connection_connect(new);
return new;
}
-static void connection_handler(IOCHAN i, int event)
+static void non_block_events(struct connection *co)
{
- struct connection *co = iochan_getdata(i);
+ struct client *cl = co->client;
+ IOCHAN iochan = co->iochan;
+ ZOOM_connection link = co->link;
+ while (1)
+ {
+ int ev;
+ int r = ZOOM_event_nonblock(1, &link);
+ if (!r)
+ break;
+ ev = ZOOM_connection_last_event(link);
+#if 0
+ yaz_log(YLOG_LOG, "ZOOM_EVENT_%s", ZOOM_get_event_str(ev));
+#endif
+ switch (ev)
+ {
+ case ZOOM_EVENT_END:
+ {
+ const char *error, *addinfo;
+ if (ZOOM_connection_error(link, &error, &addinfo))
+ {
+ yaz_log(YLOG_LOG, "Error %s from %s",
+ error, client_get_url(cl));
+ }
+ client_set_state(cl, Client_Idle);
+ }
+ break;
+ case ZOOM_EVENT_SEND_DATA:
+ break;
+ case ZOOM_EVENT_RECV_DATA:
+ break;
+ case ZOOM_EVENT_UNKNOWN:
+ break;
+ case ZOOM_EVENT_SEND_APDU:
+ client_set_state(co->client, Client_Working);
+ break;
+ case ZOOM_EVENT_RECV_APDU:
+ break;
+ case ZOOM_EVENT_CONNECT:
+ yaz_log(YLOG_LOG, "Connected to %s", client_get_url(cl));
+ co->state = Conn_Open;
+ iochan_settimeout(iochan, global_parameters.z3950_session_timeout);
+ break;
+ case ZOOM_EVENT_RECV_SEARCH:
+ client_search_response(cl);
+ break;
+ case ZOOM_EVENT_RECV_RECORD:
+ client_record_response(cl);
+ break;
+ default:
+ yaz_log(YLOG_LOG, "Unhandled event (%d) from %s",
+ ev, client_get_url(cl));
+ }
+ }
+}
+
+void connection_continue(struct connection *co)
+{
+ non_block_events(co);
+}
+
+static void connection_handler(IOCHAN iochan, int event)
+{
+ struct connection *co = iochan_getdata(iochan);
struct client *cl = co->client;
struct session *se = 0;
yaz_log(YLOG_LOG, "idle timeout %s", client_get_url(cl));
connection_destroy(co);
}
- return;
}
else
{
- ZOOM_connection link = co->link;
+ non_block_events(co);
- if (ZOOM_event(1, &link))
- {
- do
- {
- int event = ZOOM_connection_last_event(link);
- switch (event)
- {
- case ZOOM_EVENT_END:
- break;
- case ZOOM_EVENT_SEND_DATA:
- break;
- case ZOOM_EVENT_RECV_DATA:
- break;
- case ZOOM_EVENT_UNKNOWN:
- break;
- case ZOOM_EVENT_SEND_APDU:
- client_set_state(co->client, Client_Working);
- break;
- case ZOOM_EVENT_RECV_APDU:
- client_set_state(co->client, Client_Idle);
- break;
- case ZOOM_EVENT_CONNECT:
- yaz_log(YLOG_LOG, "Connected to %s", client_get_url(cl));
- co->state = Conn_Open;
- client_set_state(co->client, Client_Connected);
- iochan_settimeout(i, global_parameters.z3950_session_timeout);
- break;
- case ZOOM_EVENT_RECV_SEARCH:
- yaz_log(YLOG_LOG, "Search response from %s", client_get_url(cl));
- client_search_response(cl);
- break;
- case ZOOM_EVENT_RECV_RECORD:
- yaz_log(YLOG_LOG, "Record from %s", client_get_url(cl));
- client_record_response(cl);
- break;
- default:
- yaz_log(YLOG_LOG, "Unhandled event (%d) from %s",
- event, client_get_url(cl));
- }
- }
- while (ZOOM_event_nonblock(1, &link));
- }
+ ZOOM_connection_fire_event_socket(co->link, event);
+
+ non_block_events(co);
}
}
return ZOOM_connection_get_mask(co->link);
}
-int connection_connect(struct connection *con)
+static int connection_connect(struct connection *con)
{
ZOOM_connection link = 0;
struct host *host = connection_get_host(con);
assert(con);
ZOOM_options_set(zoptions, "async", "1");
- ZOOM_options_set(zoptions, "implementationName",
- global_parameters.implementationName);
- ZOOM_options_set(zoptions, "implementationVersion",
- global_parameters.implementationVersion);
+ ZOOM_options_set(zoptions, "implementationName", PACKAGE_NAME);
+ ZOOM_options_set(zoptions, "implementationVersion", VERSION);
if (zproxy && *zproxy)
{
con->zproxy = xstrdup(zproxy);
if (sru && *sru)
strcpy(ipport, "http://");
strcat(ipport, host->ipport);
- /* deal with SRU path here because databaseName option is not read in
- ZOOM in SRU mode */
- if (sru && *sru)
- {
- if (*sdb->database->databases[0])
- {
- strcat(ipport, "/");
- strcat(ipport, sdb->database->databases[0]);
- }
- }
+
ZOOM_connection_connect(link, ipport, 0);
con->link = link;
connection_release(co);
client_set_connection(cl, co);
co->client = cl;
+ /* tells ZOOM to reconnect if necessary. Disabled becuase
+ the ZOOM_connection_connect flushes the task queue */
+ ZOOM_connection_connect(co->link, 0, 0);
}
else
+ {
co = connection_create(cl);
+ }
}
if (co && co->link)
/*
* Local variables:
* c-basic-offset: 4
+ * c-file-style: "Stroustrup"
* indent-tabs-mode: nil
* End:
* vim: shiftwidth=4 tabstop=8 expandtab
*/
+