X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fzoom-c.c;h=10cf7905560c4747e3816e76090afe31759df5ce;hb=db93359f0cbf9a1e9dc81ea05f7b8662f843ae3d;hp=61e08a80cec63dcd86da6a5626a29a045f7aa24b;hpb=31de2e747e8aab81f5de5867e237ec1f0eda5f62;p=yaz-moved-to-github.git diff --git a/src/zoom-c.c b/src/zoom-c.c index 61e08a8..10cf790 100644 --- a/src/zoom-c.c +++ b/src/zoom-c.c @@ -1,8 +1,8 @@ /* - * 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.100 2006-11-30 17:07:50 mike Exp $ + * $Id: zoom-c.c,v 1.118 2007-03-19 20:58:34 adam Exp $ */ /** * \file zoom-c.c @@ -27,25 +27,6 @@ #include #include -#if HAVE_SYS_TYPES_H -#include -#endif -#if HAVE_SYS_TIME_H -#include -#endif -#if HAVE_SYS_POLL_H -#include -#endif -#if HAVE_SYS_SELECT_H -#include -#endif -#ifdef WIN32 -#if FD_SETSIZE < 512 -#define FD_SETSIZE 512 -#endif -#include -#endif - static int log_api = 0; static int log_details = 0; @@ -54,10 +35,26 @@ typedef enum { 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; @@ -122,6 +119,21 @@ static ZOOM_Event ZOOM_connection_get_event(ZOOM_connection c) 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, @@ -148,11 +160,14 @@ static void set_dset_error(ZOOM_connection c, int error, } 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 @@ -163,6 +178,7 @@ static void set_HTTP_error(ZOOM_connection c, int error, } #endif + static void set_ZOOM_error(ZOOM_connection c, int error, const char *addinfo) { @@ -178,6 +194,8 @@ static void clear_error(ZOOM_connection c) * 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: @@ -261,12 +279,12 @@ void ZOOM_connection_remove_task(ZOOM_connection c) 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; @@ -279,7 +297,7 @@ void ZOOM_connection_remove_task(ZOOM_connection c) 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: @@ -318,7 +336,7 @@ ZOOM_API(ZOOM_connection) 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; @@ -411,7 +429,7 @@ ZOOM_API(void) 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); @@ -453,15 +471,18 @@ ZOOM_API(void) else c->lang = 0; - 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); + } { /* @@ -653,8 +674,8 @@ ZOOM_API(int) 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; @@ -695,6 +716,7 @@ ZOOM_API(void) 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); @@ -831,22 +853,10 @@ ZOOM_API(ZOOM_resultset) 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; @@ -901,11 +911,11 @@ ZOOM_API(void) 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; } @@ -914,6 +924,11 @@ ZOOM_API(void) ZOOM_API(void) ZOOM_resultset_destroy(ZOOM_resultset r) { + resultset_destroy(r); +} + +static void resultset_destroy(ZOOM_resultset r) +{ if (!r) return; (r->refcount)--; @@ -960,18 +975,24 @@ static void do_close(ZOOM_connection c) 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; } @@ -1115,7 +1136,7 @@ static zoom_ret do_connect(ZOOM_connection c) /* 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; @@ -1123,12 +1144,13 @@ static zoom_ret do_connect(ZOOM_connection c) } 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; } } @@ -1137,20 +1159,6 @@ static zoom_ret do_connect(ZOOM_connection c) 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; @@ -1276,7 +1284,7 @@ static zoom_ret ZOOM_connection_send_init(ZOOM_connection c) odr_prepend(c->odr_out, "ZOOM-C", ireq->implementationName)); - version = odr_strdup(c->odr_out, "$Revision: 1.100 $"); + 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 = @@ -1578,7 +1586,7 @@ static zoom_ret ZOOM_connection_send_search(ZOOM_connection c) } 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) { @@ -1706,11 +1714,11 @@ ZOOM_API(void) 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); } @@ -1763,7 +1771,7 @@ static const char *marc_iconv_return(ZOOM_record rec, int marc_type, 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) @@ -1826,8 +1834,7 @@ static const char *record_iconv_return(ZOOM_record rec, int *len, } 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); } @@ -2265,6 +2272,8 @@ static void handle_records(ZOOM_connection c, Z_Records *sr, syntax, elementSetName); } *count -= i; + if (*count < 0) + *count = 0; *start += i; yaz_log(log_details, "handle_records resultset=%p start=%d count=%d", @@ -2416,6 +2425,16 @@ static void handle_search_response(ZOOM_connection c, Z_SearchResponse *sr) 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; @@ -2561,7 +2580,7 @@ static zoom_ret send_present(ZOOM_connection c) 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) { @@ -2581,14 +2600,14 @@ static zoom_ret send_present(ZOOM_connection c) 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) { @@ -2624,21 +2643,21 @@ static zoom_ret send_present(ZOOM_connection c) } 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; @@ -2838,11 +2857,12 @@ ZOOM_API(const char *) 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) @@ -2982,7 +3002,13 @@ static Z_ItemOrder *encode_item_order(ZOOM_package p) *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; } @@ -3288,11 +3314,12 @@ ZOOM_API(const char *) } -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) @@ -3436,11 +3463,21 @@ static void interpret_otherinformation_field(ZOOM_connection 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) { @@ -3466,6 +3503,10 @@ static void recv_apdu(ZOOM_connection c, Z_APDU *apdu) 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; @@ -3666,7 +3707,7 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) "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, "; ")) @@ -3674,8 +3715,7 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) 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, @@ -3739,11 +3779,7 @@ static int do_read(ZOOM_connection c) 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); @@ -3811,17 +3847,18 @@ static zoom_ret do_write_ex(ZOOM_connection c, char *buf_out, int len_out) } 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); } @@ -3846,18 +3883,20 @@ ZOOM_API(const char *) 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 *) @@ -3866,11 +3905,12 @@ 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; } @@ -3999,11 +4039,12 @@ static void ZOOM_connection_do_io(ZOOM_connection c, int mask) "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) { @@ -4017,7 +4058,7 @@ static void ZOOM_connection_do_io(ZOOM_connection c, int mask) /* 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; @@ -4032,12 +4073,7 @@ static void ZOOM_connection_do_io(ZOOM_connection c, int mask) { 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); @@ -4059,216 +4095,6 @@ ZOOM_API(int) 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; ioptions, "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; imask) - { - 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; imask) - { - /* 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; imask) + { + 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; imask && 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