/*
- * Copyright (C) 1995-2006, Index Data ApS
+ * Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: zoom-c.c,v 1.98 2006-11-08 08:57:34 adam Exp $
+ * $Id: zoom-c.c,v 1.118 2007-03-19 20:58:34 adam Exp $
*/
/**
* \file zoom-c.c
#include <yaz/cql.h>
#include <yaz/ccl.h>
-#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#if HAVE_SYS_POLL_H
-#include <sys/poll.h>
-#endif
-#if HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#ifdef WIN32
-#if FD_SETSIZE < 512
-#define FD_SETSIZE 512
-#endif
-#include <winsock.h>
-#endif
-
static int log_api = 0;
static int log_details = 0;
zoom_complete
} zoom_ret;
+static void resultset_destroy(ZOOM_resultset r);
static zoom_ret ZOOM_connection_send_init(ZOOM_connection c);
static zoom_ret do_write_ex(ZOOM_connection c, char *buf_out, int len_out);
static char *cql2pqf(ZOOM_connection c, const char *cql);
+
+/*
+ * This wrapper is just for logging failed lookups. It would be nicer
+ * if it could cause failure when a lookup fails, but that's hard.
+ */
+static Odr_oid *zoom_yaz_str_to_z3950oid(ZOOM_connection c,
+ int oid_class, const char *str) {
+ Odr_oid *res = yaz_str_to_z3950oid(c->odr_out, oid_class, str);
+ if (res == 0)
+ yaz_log(YLOG_WARN, "%p OID lookup (%d, '%s') failed",
+ c, (int) oid_class, str);
+ return res;
+}
+
+
static void initlog(void)
{
static int log_level_initialized = 0;
return event;
}
+static void ZOOM_connection_remove_events(ZOOM_connection c)
+{
+ ZOOM_Event event;
+ while ((event = ZOOM_connection_get_event(c)))
+ ZOOM_Event_destroy(event);
+}
+
+ZOOM_API(int) ZOOM_connection_peek_event(ZOOM_connection c)
+{
+ ZOOM_Event event = c->m_queue_front;
+
+ return event ? event->kind : ZOOM_EVENT_NONE;
+}
+
+void ZOOM_connection_remove_tasks(ZOOM_connection c);
static void set_dset_error(ZOOM_connection c, int error,
const char *dset,
}
else if (addinfo)
c->addinfo = xstrdup(addinfo);
- if (error)
+ if (error != ZOOM_ERROR_NONE)
+ {
yaz_log(log_api, "%p set_dset_error %s %s:%d %s %s",
c, c->host_port ? c->host_port : "<>", dset, error,
addinfo ? addinfo : "",
addinfo2 ? addinfo2 : "");
+ ZOOM_connection_remove_tasks(c);
+ }
}
#if YAZ_HAVE_XML2
}
#endif
+
static void set_ZOOM_error(ZOOM_connection c, int error,
const char *addinfo)
{
* or Init Refused are not cleared, because they are not
* recoverable: doing another search doesn't help.
*/
+
+ ZOOM_connection_remove_events(c);
switch (c->error)
{
case ZOOM_ERROR_CONNECT:
switch (task->which)
{
case ZOOM_TASK_SEARCH:
- ZOOM_resultset_destroy(task->u.search.resultset);
+ resultset_destroy(task->u.search.resultset);
xfree(task->u.search.syntax);
xfree(task->u.search.elementSetName);
break;
case ZOOM_TASK_RETRIEVE:
- ZOOM_resultset_destroy(task->u.retrieve.resultset);
+ resultset_destroy(task->u.retrieve.resultset);
xfree(task->u.retrieve.syntax);
xfree(task->u.retrieve.elementSetName);
break;
ZOOM_package_destroy(task->u.package);
break;
case ZOOM_TASK_SORT:
- ZOOM_resultset_destroy(task->u.sort.resultset);
+ resultset_destroy(task->u.sort.resultset);
ZOOM_query_destroy(task->u.sort.q);
break;
default:
c->proto = PROTO_Z3950;
c->cs = 0;
- c->mask = 0;
+ ZOOM_connection_set_mask(c, 0);
c->reconnect_ok = 0;
c->state = STATE_IDLE;
c->addinfo = 0;
initlog();
yaz_log(log_api, "%p ZOOM_connection_connect host=%s portnum=%d",
- c, host, portnum);
+ c, host ? host : "null", portnum);
set_ZOOM_error(c, ZOOM_ERROR_NONE, 0);
ZOOM_connection_remove_tasks(c);
else
c->lang = 0;
- val = ZOOM_options_get(c->options, "sru");
- c->sru_mode = get_sru_mode_from_string(val);
-
- xfree(c->host_port);
- if (portnum)
+ if (host)
{
- char hostn[128];
- sprintf(hostn, "%.80s:%d", host, portnum);
- c->host_port = xstrdup(hostn);
- }
- else
- c->host_port = xstrdup(host);
+ xfree(c->host_port);
+ if (portnum)
+ {
+ char hostn[128];
+ sprintf(hostn, "%.80s:%d", host, portnum);
+ c->host_port = xstrdup(hostn);
+ }
+ else
+ c->host_port = xstrdup(host);
+ }
{
/*
}
}
+ val = ZOOM_options_get(c->options, "sru");
+ c->sru_mode = get_sru_mode_from_string(val);
+
ZOOM_options_set(c->options, "host", c->host_port);
val = ZOOM_options_get(c->options, "cookie");
WRBUF wr = wrbuf_alloc();
ccl_pquery(wr, rpn);
ccl_rpn_delete(rpn);
- ret = ZOOM_query_prefix(s, wrbuf_buf(wr));
- wrbuf_free(wr, 1);
+ ret = ZOOM_query_prefix(s, wrbuf_cstr(wr));
+ wrbuf_destroy(wr);
}
ccl_qual_rm(&bibset);
return ret;
odr_destroy(c->odr_out);
ZOOM_options_destroy(c->options);
ZOOM_connection_remove_tasks(c);
+ ZOOM_connection_remove_events(c);
xfree(c->host_port);
xfree(c->path);
xfree(c->proxy);
return r;
}
-/*
- * This is the old result-set sorting API, which is maintained only
- * for the sake of binary compatibility. There is no reason ever to
- * use this rather than ZOOM_resultset_sort1().
- */
-ZOOM_API(void)
+ZOOM_API(int)
ZOOM_resultset_sort(ZOOM_resultset r,
const char *sort_type, const char *sort_spec)
{
- (void) ZOOM_resultset_sort1(r, sort_type, sort_spec);
-}
-
-ZOOM_API(int)
- ZOOM_resultset_sort1(ZOOM_resultset r,
- const char *sort_type, const char *sort_spec)
-{
ZOOM_connection c = r->connection;
ZOOM_task task;
ZOOM_query newq;
for (rc = r->record_hash[i]; rc; rc = rc->next)
{
if (rc->rec.wrbuf_marc)
- wrbuf_free(rc->rec.wrbuf_marc, 1);
+ wrbuf_destroy(rc->rec.wrbuf_marc);
if (rc->rec.wrbuf_iconv)
- wrbuf_free(rc->rec.wrbuf_iconv, 1);
+ wrbuf_destroy(rc->rec.wrbuf_iconv);
if (rc->rec.wrbuf_opac)
- wrbuf_free(rc->rec.wrbuf_opac, 1);
+ wrbuf_destroy(rc->rec.wrbuf_opac);
}
r->record_hash[i] = 0;
}
ZOOM_API(void)
ZOOM_resultset_destroy(ZOOM_resultset r)
{
+ resultset_destroy(r);
+}
+
+static void resultset_destroy(ZOOM_resultset r)
+{
if (!r)
return;
(r->refcount)--;
if (c->cs)
cs_close(c->cs);
c->cs = 0;
- c->mask = 0;
+ ZOOM_connection_set_mask(c, 0);
c->state = STATE_IDLE;
}
static int ZOOM_test_reconnect(ZOOM_connection c)
{
+ ZOOM_Event event;
+
if (!c->reconnect_ok)
return 0;
do_close(c);
c->reconnect_ok = 0;
c->tasks->running = 0;
ZOOM_connection_insert_task(c, ZOOM_TASK_CONNECT);
+
+ event = ZOOM_Event_create(ZOOM_EVENT_CONNECT);
+ ZOOM_connection_put_event(c, event);
+
return 1;
}
/* no init request for SRW .. */
assert(c->tasks->which == ZOOM_TASK_CONNECT);
ZOOM_connection_remove_task(c);
- c->mask = 0;
+ ZOOM_connection_set_mask(c, 0);
ZOOM_connection_exec_task(c);
}
c->state = STATE_ESTABLISHED;
}
else if (ret > 0)
{
- c->state = STATE_CONNECTING;
- c->mask = ZOOM_SELECT_EXCEPT;
+ int mask = ZOOM_SELECT_EXCEPT;
if (c->cs->io_pending & CS_WANT_WRITE)
- c->mask += ZOOM_SELECT_WRITE;
+ mask += ZOOM_SELECT_WRITE;
if (c->cs->io_pending & CS_WANT_READ)
- c->mask += ZOOM_SELECT_READ;
+ mask += ZOOM_SELECT_READ;
+ ZOOM_connection_set_mask(c, mask);
+ c->state = STATE_CONNECTING;
return zoom_pending;
}
}
return zoom_complete;
}
-int z3950_connection_socket(ZOOM_connection c)
-{
- if (c->cs)
- return cs_fileno(c->cs);
- return -1;
-}
-
-int z3950_connection_mask(ZOOM_connection c)
-{
- if (c->cs)
- return c->mask;
- return 0;
-}
-
static void otherInfo_attach(ZOOM_connection c, Z_APDU *a, ODR out)
{
int i;
odr_prepend(c->odr_out, "ZOOM-C",
ireq->implementationName));
- version = odr_strdup(c->odr_out, "$Revision: 1.98 $");
+ version = odr_strdup(c->odr_out, "$Revision: 1.118 $");
if (strlen(version) > 10) /* check for unexpanded CVS strings */
version[strlen(version)-2] = '\0';
ireq->implementationVersion =
}
if (syntax)
search_req->preferredRecordSyntax =
- yaz_str_to_z3950oid(c->odr_out, CLASS_RECSYN, syntax);
+ zoom_yaz_str_to_z3950oid(c, CLASS_RECSYN, syntax);
if (!r->setname)
{
if (!rec)
return;
if (rec->wrbuf_marc)
- wrbuf_free(rec->wrbuf_marc, 1);
+ wrbuf_destroy(rec->wrbuf_marc);
if (rec->wrbuf_iconv)
- wrbuf_free(rec->wrbuf_iconv, 1);
+ wrbuf_destroy(rec->wrbuf_iconv);
if (rec->wrbuf_opac)
- wrbuf_free(rec->wrbuf_opac, 1);
+ wrbuf_destroy(rec->wrbuf_opac);
odr_destroy(rec->odr);
xfree(rec);
}
yaz_iconv_close(cd);
if (len)
*len = wrbuf_len(rec->wrbuf_marc);
- return wrbuf_buf(rec->wrbuf_marc);
+ return wrbuf_cstr(rec->wrbuf_marc);
}
yaz_marc_destroy(mt);
if (cd)
}
wrbuf_write(rec->wrbuf_iconv, outbuf, outp - outbuf);
}
- wrbuf_puts(rec->wrbuf_iconv, "");
- buf = wrbuf_buf(rec->wrbuf_iconv);
+ buf = wrbuf_cstr(rec->wrbuf_iconv);
sz = wrbuf_len(rec->wrbuf_iconv);
yaz_iconv_close(cd);
}
syntax, elementSetName);
}
*count -= i;
+ if (*count < 0)
+ *count = 0;
*start += i;
yaz_log(log_details,
"handle_records resultset=%p start=%d count=%d",
resultset = c->tasks->u.search.resultset;
+ if (sr->resultSetStatus)
+ {
+ ZOOM_options_set_int(resultset->options, "resultSetStatus",
+ *sr->resultSetStatus);
+ }
+ if (sr->presentStatus)
+ {
+ ZOOM_options_set_int(resultset->options, "presentStatus",
+ *sr->presentStatus);
+ }
handle_searchResult(c, resultset, sr->additionalSearchInfo);
resultset->size = *sr->resultCount;
if (syntax && *syntax)
req->preferredRecordSyntax =
- yaz_str_to_z3950oid(c->odr_out, CLASS_RECSYN, syntax);
+ zoom_yaz_str_to_z3950oid(c, CLASS_RECSYN, syntax);
if (resultset->schema && *resultset->schema)
{
compo->u.complex->generic->which = Z_Schema_oid;
compo->u.complex->generic->schema.oid = (Odr_oid *)
- yaz_str_to_z3950oid (c->odr_out, CLASS_SCHEMA, resultset->schema);
+ zoom_yaz_str_to_z3950oid (c, CLASS_SCHEMA, resultset->schema);
if (!compo->u.complex->generic->schema.oid)
{
/* OID wasn't a schema! Try record syntax instead. */
compo->u.complex->generic->schema.oid = (Odr_oid *)
- yaz_str_to_z3950oid (c->odr_out, CLASS_RECSYN, resultset->schema);
+ zoom_yaz_str_to_z3950oid (c, CLASS_RECSYN, resultset->schema);
}
if (elementSetName && *elementSetName)
{
}
ZOOM_API(ZOOM_scanset)
- ZOOM_connection_scan(ZOOM_connection c, const char *start)
+ ZOOM_connection_scan_pqf(ZOOM_connection c, const char *start)
{
ZOOM_scanset s;
ZOOM_query q = ZOOM_query_create();
ZOOM_query_prefix(q, start);
- s = ZOOM_connection_scan1(c, q);
+ s = ZOOM_connection_scan(c, q);
ZOOM_query_destroy(q);
return s;
}
ZOOM_API(ZOOM_scanset)
- ZOOM_connection_scan1(ZOOM_connection c, ZOOM_query q)
+ ZOOM_connection_scan(ZOOM_connection c, ZOOM_query q)
{
char *start;
char *freeme = 0;
return ZOOM_options_get(scan->options, key);
}
-ZOOM_API(void)
+ZOOM_API(int)
ZOOM_scanset_option_set(ZOOM_scanset scan, const char *key,
const char *val)
{
ZOOM_options_set(scan->options, key, val);
+ return 0;
}
static Z_APDU *create_es_package(ZOOM_package p, int type)
*req->u.esRequest->notToKeep->resultSetItem->item =
(str ? atoi(str) : 1);
}
- req->u.esRequest->notToKeep->itemRequest = encode_ill_request(p);
+
+ str = ZOOM_options_get(p->options, "doc");
+ if (str)
+ req->u.esRequest->notToKeep->itemRequest =
+ z_ext_record(p->odr_out, VAL_TEXT_XML, str, strlen(str));
+ else
+ req->u.esRequest->notToKeep->itemRequest = encode_ill_request(p);
return req;
}
}
-ZOOM_API(void)
+ZOOM_API(int)
ZOOM_package_option_set(ZOOM_package p, const char *key,
const char *val)
{
ZOOM_options_set(p->options, key, val);
+ return 0;
}
static int ZOOM_connection_exec_task(ZOOM_connection c)
c, task->which, task->running);
if (c->error != ZOOM_ERROR_NONE)
{
- yaz_log(YLOG_LOG, "%p ZOOM_connection_exec_task "
- "removing tasks because of error = %d", c, c->error);
yaz_log(log_details, "%p ZOOM_connection_exec_task "
"removing tasks because of error = %d", c, c->error);
ZOOM_connection_remove_tasks(c);
}
}
+
+static void set_init_option(const char *name, void *clientData) {
+ ZOOM_connection c = clientData;
+ char buf[80];
+
+ sprintf(buf, "init_opt_%.70s", name);
+ ZOOM_connection_option_set(c, buf, "1");
+}
+
+
static void recv_apdu(ZOOM_connection c, Z_APDU *apdu)
{
Z_InitResponse *initrs;
- c->mask = 0;
+ ZOOM_connection_set_mask(c, 0);
yaz_log(log_details, "%p recv_apdu apdu->which=%d", c, apdu->which);
switch(apdu->which)
{
ZOOM_connection_option_set(c, "targetImplementationVersion",
initrs->implementationVersion ?
initrs->implementationVersion : "");
+
+ /* Make initrs->options available as ZOOM-level options */
+ yaz_init_opt_decode(initrs->options, set_init_option, (void*) c);
+
if (!*initrs->result)
{
Z_External *uif = initrs->userInformationField;
"Content-Type");
const char *connection_head = z_HTTP_header_lookup(hres->headers,
"Connection");
- c->mask = 0;
+ ZOOM_connection_set_mask(c, 0);
yaz_log(log_details, "%p handle_http", c);
if (content_type && !yaz_strcmp_del("text/xml", content_type, "; "))
Z_SOAP *soap_package = 0;
ODR o = c->odr_in;
Z_SOAP_Handler soap_handlers[2] = {
- {"http://www.loc.gov/zing/srw/", 0,
- (Z_SOAP_fun) yaz_srw_codec},
+ {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
{0, 0, 0}
};
ret = z_soap_codec(o, &soap_package,
return 0;
if (r <= 0)
{
- if (ZOOM_test_reconnect(c))
- {
- yaz_log(log_details, "%p do_read reconnect read", c);
- }
- else
+ if (!ZOOM_test_reconnect(c))
{
set_ZOOM_error(c, ZOOM_ERROR_CONNECTION_LOST, c->host_port);
do_close(c);
}
else if (r == 1)
{
- c->mask = ZOOM_SELECT_EXCEPT;
+ int mask = ZOOM_SELECT_EXCEPT;
if (c->cs->io_pending & CS_WANT_WRITE)
- c->mask += ZOOM_SELECT_WRITE;
+ mask += ZOOM_SELECT_WRITE;
if (c->cs->io_pending & CS_WANT_READ)
- c->mask += ZOOM_SELECT_READ;
+ mask += ZOOM_SELECT_READ;
+ ZOOM_connection_set_mask(c, mask);
yaz_log(log_details, "%p do_write_ex write incomplete mask=%d",
c, c->mask);
}
else
{
- c->mask = ZOOM_SELECT_READ|ZOOM_SELECT_EXCEPT;
+ ZOOM_connection_set_mask(c, ZOOM_SELECT_READ|ZOOM_SELECT_EXCEPT);
yaz_log(log_details, "%p do_write_ex write complete mask=%d",
c, c->mask);
}
return ZOOM_options_getl(c->options, key, lenp);
}
-ZOOM_API(void)
+ZOOM_API(int)
ZOOM_connection_option_set(ZOOM_connection c, const char *key,
const char *val)
{
ZOOM_options_set(c->options, key, val);
+ return 0;
}
-ZOOM_API(void)
+ZOOM_API(int)
ZOOM_connection_option_setl(ZOOM_connection c, const char *key,
const char *val, int len)
{
ZOOM_options_setl(c->options, key, val, len);
+ return 0;
}
ZOOM_API(const char *)
return ZOOM_options_get(r->options, key);
}
-ZOOM_API(void)
+ZOOM_API(int)
ZOOM_resultset_option_set(ZOOM_resultset r, const char *key,
const char *val)
{
ZOOM_options_set(r->options, key, val);
+ return 0;
}
"cs_rcvconnect returned %d", c, ret);
if (ret == 1)
{
- c->mask = ZOOM_SELECT_EXCEPT;
+ int mask = ZOOM_SELECT_EXCEPT;
if (c->cs->io_pending & CS_WANT_WRITE)
- c->mask += ZOOM_SELECT_WRITE;
+ mask += ZOOM_SELECT_WRITE;
if (c->cs->io_pending & CS_WANT_READ)
- c->mask += ZOOM_SELECT_READ;
+ mask += ZOOM_SELECT_READ;
+ ZOOM_connection_set_mask(c, mask);
}
else if (ret == 0)
{
/* no init request for SRW .. */
assert(c->tasks->which == ZOOM_TASK_CONNECT);
ZOOM_connection_remove_task(c);
- c->mask = 0;
+ ZOOM_connection_set_mask(c, 0);
ZOOM_connection_exec_task(c);
}
c->state = STATE_ESTABLISHED;
{
if (mask & ZOOM_SELECT_EXCEPT)
{
- if (ZOOM_test_reconnect(c))
- {
- event = ZOOM_Event_create(ZOOM_EVENT_CONNECT);
- ZOOM_connection_put_event(c, event);
- }
- else
+ if (!ZOOM_test_reconnect(c))
{
set_ZOOM_error(c, ZOOM_ERROR_CONNECTION_LOST, c->host_port);
do_close(c);
return cs->last_event;
}
-ZOOM_API(int)
- ZOOM_event(int no, ZOOM_connection *cs)
-{
- int timeout = 30; /* default timeout in seconds */
- int timeout_set = 0; /* whether it was overriden at all */
-#if HAVE_SYS_POLL_H
- struct pollfd pollfds[1024];
- ZOOM_connection poll_cs[1024];
-#else
- struct timeval tv;
- fd_set input, output, except;
-#endif
- int i, r, nfds;
- int max_fd = 0;
-
- yaz_log(log_details, "ZOOM_event(no=%d,cs=%p)", no, cs);
-
- for (i = 0; i<no; i++)
- {
- ZOOM_connection c = cs[i];
- ZOOM_Event event;
-
-#if 0
- if (c)
- ZOOM_connection_show_tasks(c);
-#endif
-
- if (c && (event = ZOOM_connection_get_event(c)))
- {
- ZOOM_Event_destroy(event);
- return i+1;
- }
- }
- for (i = 0; i<no; i++)
- {
- ZOOM_connection c = cs[i];
- if (c)
- {
- ZOOM_Event event;
- ZOOM_connection_exec_task(c);
- if ((event = ZOOM_connection_get_event(c)))
- {
- ZOOM_Event_destroy(event);
- return i+1;
- }
- }
- }
-#if HAVE_SYS_POLL_H
-
-#else
- FD_ZERO(&input);
- FD_ZERO(&output);
- FD_ZERO(&except);
-#endif
- nfds = 0;
- for (i = 0; i<no; i++)
- {
- ZOOM_connection c = cs[i];
- int fd, mask;
- int this_timeout;
-
- if (!c)
- continue;
- fd = z3950_connection_socket(c);
- mask = z3950_connection_mask(c);
-
- if (fd == -1)
- continue;
- if (max_fd < fd)
- max_fd = fd;
-
- /* -1 is used for indefinite timeout (no timeout), so -2 here. */
- this_timeout = ZOOM_options_get_int(c->options, "timeout", -2);
- if (this_timeout != -2)
- {
- /* ensure the minimum timeout is used */
- if (!timeout_set)
- timeout = this_timeout;
- else if (this_timeout != -1 && this_timeout < timeout)
- timeout = this_timeout;
- timeout_set = 1;
- }
-#if HAVE_SYS_POLL_H
- if (mask)
- {
- short poll_events = 0;
-
- if (mask & ZOOM_SELECT_READ)
- poll_events += POLLIN;
- if (mask & ZOOM_SELECT_WRITE)
- poll_events += POLLOUT;
- if (mask & ZOOM_SELECT_EXCEPT)
- poll_events += POLLERR;
- pollfds[nfds].fd = fd;
- pollfds[nfds].events = poll_events;
- pollfds[nfds].revents = 0;
- poll_cs[nfds] = c;
- nfds++;
- }
-#else
- if (mask & ZOOM_SELECT_READ)
- {
- FD_SET(fd, &input);
- nfds++;
- }
- if (mask & ZOOM_SELECT_WRITE)
- {
- FD_SET(fd, &output);
- nfds++;
- }
- if (mask & ZOOM_SELECT_EXCEPT)
- {
- FD_SET(fd, &except);
- nfds++;
- }
-#endif
- }
- if (!nfds)
- return 0;
-
-#if HAVE_SYS_POLL_H
- while ((r = poll(pollfds, nfds,
- (timeout == -1 ? -1 : timeout * 1000))) < 0
- && errno == EINTR)
- {
- ;
- }
- if (r < 0)
- yaz_log(YLOG_WARN|YLOG_ERRNO, "ZOOM_event: poll");
- for (i = 0; i<nfds; i++)
- {
- ZOOM_connection c = poll_cs[i];
- if (r && c->mask)
- {
- int mask = 0;
- if (pollfds[i].revents & POLLIN)
- mask += ZOOM_SELECT_READ;
- if (pollfds[i].revents & POLLOUT)
- mask += ZOOM_SELECT_WRITE;
- if (pollfds[i].revents & POLLERR)
- mask += ZOOM_SELECT_EXCEPT;
- if (mask)
- ZOOM_connection_do_io(c, mask);
- }
- else if (r == 0 && c->mask)
- {
- ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_TIMEOUT);
- /* timeout and this connection was waiting */
- set_ZOOM_error(c, ZOOM_ERROR_TIMEOUT, 0);
- do_close(c);
- ZOOM_connection_put_event(c, event);
- }
- }
-#else
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
-
- while ((r = select(max_fd+1, &input, &output, &except,
- (timeout == -1 ? 0 : &tv))) < 0 && errno == EINTR)
- {
- ;
- }
- if (r < 0)
- yaz_log(YLOG_WARN|YLOG_ERRNO, "ZOOM_event: select");
-
- r = select(max_fd+1, &input, &output, &except, (timeout == -1 ? 0 : &tv));
- for (i = 0; i<no; i++)
- {
- ZOOM_connection c = cs[i];
- int fd, mask;
-
- if (!c)
- continue;
- fd = z3950_connection_socket(c);
- mask = 0;
- if (r && c->mask)
- {
- /* no timeout and real socket */
- if (FD_ISSET(fd, &input))
- mask += ZOOM_SELECT_READ;
- if (FD_ISSET(fd, &output))
- mask += ZOOM_SELECT_WRITE;
- if (FD_ISSET(fd, &except))
- mask += ZOOM_SELECT_EXCEPT;
- if (mask)
- ZOOM_connection_do_io(c, mask);
- }
- if (r == 0 && c->mask)
- {
- ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_TIMEOUT);
- /* timeout and this connection was waiting */
- set_ZOOM_error(c, ZOOM_ERROR_TIMEOUT, 0);
- do_close(c);
- ZOOM_connection_put_event(c, event);
- }
- }
-#endif
- for (i = 0; i<no; i++)
- {
- ZOOM_connection c = cs[i];
- ZOOM_Event event;
- if (c && (event = ZOOM_connection_get_event(c)))
- {
- ZOOM_Event_destroy(event);
- return i+1;
- }
- }
- return 0;
-}
-
/*
* Returns an xmalloc()d string containing RPN that corresponds to the
return xstrdup(pqfbuf);
}
+ZOOM_API(int) ZOOM_connection_fire_event_timeout(ZOOM_connection c)
+{
+ if (c->mask)
+ {
+ ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_TIMEOUT);
+ /* timeout and this connection was waiting */
+ set_ZOOM_error(c, ZOOM_ERROR_TIMEOUT, 0);
+ do_close(c);
+ ZOOM_connection_put_event(c, event);
+ }
+ return 0;
+}
+
+ZOOM_API(int)
+ ZOOM_connection_process(ZOOM_connection c)
+{
+ ZOOM_Event event;
+ if (!c)
+ return 0;
+
+ event = ZOOM_connection_get_event(c);
+ if (event)
+ {
+ ZOOM_Event_destroy(event);
+ return 1;
+ }
+ ZOOM_connection_exec_task(c);
+ event = ZOOM_connection_get_event(c);
+ if (event)
+ {
+ ZOOM_Event_destroy(event);
+ return 1;
+ }
+ return 0;
+}
+
+ZOOM_API(int)
+ ZOOM_event_nonblock(int no, ZOOM_connection *cs)
+{
+ int i;
+
+ yaz_log(log_details, "ZOOM_process_event(no=%d,cs=%p)", no, cs);
+
+ for (i = 0; i<no; i++)
+ {
+ ZOOM_connection c = cs[i];
+
+ if (c && ZOOM_connection_process(c))
+ return i+1;
+ }
+ return 0;
+}
+
+ZOOM_API(int) ZOOM_connection_fire_event_socket(ZOOM_connection c, int mask)
+{
+ if (c->mask && mask)
+ ZOOM_connection_do_io(c, mask);
+ return 0;
+}
+
+ZOOM_API(int) ZOOM_connection_get_socket(ZOOM_connection c)
+{
+ if (c->cs)
+ return cs_fileno(c->cs);
+ return -1;
+}
+
+ZOOM_API(int) ZOOM_connection_set_mask(ZOOM_connection c, int mask)
+{
+ c->mask = mask;
+ if (!c->cs)
+ return -1;
+ return 0;
+}
+
+ZOOM_API(int) ZOOM_connection_get_mask(ZOOM_connection c)
+{
+ if (c->cs)
+ return c->mask;
+ return 0;
+}
+
+ZOOM_API(int) ZOOM_connection_get_timeout(ZOOM_connection c)
+{
+ return ZOOM_options_get_int(c->options, "timeout", 30);
+}
+
/*
* Local variables:
* c-basic-offset: 4