+ connection_use(1);
+ return co;
+}
+
+static void non_block_events(struct connection *co)
+{
+ int got_records = 0;
+ IOCHAN iochan = co->iochan;
+ ZOOM_connection link = co->link;
+ while (1)
+ {
+ struct client *cl = co->client;
+ int ev;
+ int r = ZOOM_event_nonblock(1, &link);
+ if (!r)
+ break;
+ if (!cl)
+ continue;
+ ev = ZOOM_connection_last_event(link);
+
+#if 1
+ yaz_log(YLOG_DEBUG, "%p Connection ZOOM_EVENT_%s", co, ZOOM_get_event_str(ev));
+#endif
+ switch (ev)
+ {
+ case ZOOM_EVENT_END:
+ {
+ const char *error, *addinfo;
+ int err;
+ if ((err = ZOOM_connection_error(link, &error, &addinfo)))
+ {
+ yaz_log(YLOG_LOG, "Error %s from %s",
+ error, client_get_id(cl));
+ client_set_diagnostic(cl, err, error, addinfo);
+ client_set_state(cl, Client_Error);
+ }
+ else
+ {
+ iochan_settimeout(iochan, co->session_timeout);
+ client_set_state(cl, Client_Idle);
+ }
+ yaz_cond_broadcast(co->host->cond_ready);
+ }
+ 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);
+ iochan_settimeout(iochan, co->operation_timeout);
+ break;
+ case ZOOM_EVENT_RECV_APDU:
+ break;
+ case ZOOM_EVENT_CONNECT:
+ yaz_log(YLOG_LOG, "Connected to %s", client_get_id(cl));
+ co->state = Conn_Open;
+ break;
+ case ZOOM_EVENT_RECV_SEARCH:
+ client_search_response(cl);
+ break;
+ case ZOOM_EVENT_RECV_RECORD:
+ client_record_response(cl);
+ got_records = 1;
+ break;
+ default:
+ yaz_log(YLOG_LOG, "Unhandled event (%d) from %s",
+ ev, client_get_id(cl));
+ break;
+ }
+ }
+ if (got_records)
+ {
+ struct client *cl = co->client;
+ if (cl)
+ {
+ client_check_preferred_watch(cl);
+ client_got_records(cl);
+ }
+ }
+}
+
+void connection_continue(struct connection *co)
+{
+ int r = ZOOM_connection_exec_task(co->link);
+ if (!r)
+ {
+ const char *error, *addinfo;
+ int err;
+ if ((err = ZOOM_connection_error(co->link, &error, &addinfo)))
+ {
+ if (co->client)
+ {
+ yaz_log(YLOG_LOG, "Error %s from %s",
+ error, client_get_id(co->client));
+ client_set_diagnostic(co->client, err, error, addinfo);
+ client_set_state_nb(co->client, Client_Error);
+ }
+ }
+ }