X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fconnection.c;h=7913651c58bb71efbc7e4b88cd7f94a2d9151a72;hb=941e9e05bd43e7066746ef3ea7478dd65877af58;hp=196a3976e5196e18c749d75850b2ff3f5fcc34fc;hpb=ce83afcc8705467f318609f6a848b1d023d31a46;p=pazpar2-moved-to-github.git diff --git a/src/connection.c b/src/connection.c index 196a397..7913651 100644 --- a/src/connection.c +++ b/src/connection.c @@ -79,7 +79,7 @@ static int connection_is_idle(struct connection *co) 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) return 1; else return 0; @@ -94,7 +94,6 @@ static void remove_connection_from_host(struct connection *con) { struct connection **conp = &con->host->connections; assert(con); - yaz_mutex_enter(con->host->mutex); while (*conp) { if (*conp == con) @@ -104,11 +103,10 @@ static void remove_connection_from_host(struct connection *con) } conp = &(*conp)->next; } - yaz_mutex_leave(con->host->mutex); } // Close connection and recycle structure -void connection_destroy(struct connection *co) +static void connection_destroy(struct connection *co) { if (co->link) { @@ -140,11 +138,6 @@ static struct connection *connection_create(struct client *cl, new = xmalloc(sizeof(*new)); new->host = host; - yaz_mutex_enter(host->mutex); - new->next = new->host->connections; - new->host->connections = new; - yaz_mutex_leave(host->mutex); - new->client = cl; new->zproxy = 0; client_set_connection(cl, new); @@ -154,21 +147,31 @@ static struct connection *connection_create(struct client *cl, new->session_timeout = session_timeout; if (host->ipport) connection_connect(new, iochan_man); + + yaz_mutex_enter(host->mutex); + new->next = new->host->connections; + new->host->connections = new; + yaz_mutex_leave(host->mutex); + return new; } static void non_block_events(struct connection *co) { - struct client *cl = co->client; + 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 0 yaz_log(YLOG_LOG, "ZOOM_EVENT_%s", ZOOM_get_event_str(ev)); #endif @@ -209,58 +212,83 @@ static void non_block_events(struct connection *co) 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_url(cl)); } } + if (got_records) + { + struct client *cl = co->client; + if (cl) + { + client_got_records(cl); + } + } } void connection_continue(struct connection *co) { - non_block_events(co); + int r = ZOOM_connection_exec_task(co->link); + if (!r) + yaz_log(YLOG_WARN, "No task was executed for connection"); } static void connection_handler(IOCHAN iochan, int event) { struct connection *co = iochan_getdata(iochan); struct client *cl = co->client; + struct host *host = co->host; + yaz_mutex_enter(host->mutex); if (!cl) { /* no client associated with it.. We are probably getting a closed connection from the target.. Or, perhaps, an unexpected package.. We will just close the connection */ + yaz_log(YLOG_LOG, "timeout connection %p event=%d", co, event); connection_destroy(co); - return; + yaz_mutex_leave(host->mutex); } - if (event & EVENT_TIMEOUT) + else if (event & EVENT_TIMEOUT) { if (co->state == Conn_Connecting) { yaz_log(YLOG_WARN, "connect timeout %s", client_get_url(cl)); - client_fatal(cl); + + connection_destroy(co); + client_set_state(cl, Client_Error); } - else + else if (client_get_state(co->client) == Client_Idle) { yaz_log(YLOG_LOG, "idle timeout %s", client_get_url(cl)); connection_destroy(co); } + else + { + yaz_log(YLOG_LOG, "ignore timeout %s", client_get_url(cl)); + } + yaz_mutex_leave(host->mutex); } else { + yaz_mutex_leave(host->mutex); + + client_lock(cl); non_block_events(co); ZOOM_connection_fire_event_socket(co->link, event); non_block_events(co); + client_unlock(cl); } } // Disassociate connection from client -void connection_release(struct connection *co) +static void connection_release(struct connection *co) { struct client *cl = co->client; @@ -397,7 +425,7 @@ static int connection_connect(struct connection *con, iochan_man_t iochan_man) ZOOM_connection_connect(link, host->ipport, 0); con->link = link; - con->iochan = iochan_create(0, connection_handler, 0); + con->iochan = iochan_create(0, connection_handler, 0, "connection_socket"); con->state = Conn_Connecting; iochan_settimeout(con->iochan, con->operation_timeout); iochan_setdata(con->iochan, con); @@ -411,11 +439,6 @@ static int connection_connect(struct connection *con, iochan_man_t iochan_man) return 0; } -const char *connection_get_url(struct connection *co) -{ - return client_get_url(co->client); -} - // Ensure that client has a connection associated int client_prep_connection(struct client *cl, int operation_timeout, int session_timeout, @@ -458,6 +481,9 @@ int client_prep_connection(struct client *cl, connection_release(co); client_set_connection(cl, co); co->client = cl; + /* ensure that connection is only assigned to this client + by marking the client non Idle */ + client_set_state(cl, Client_Working); yaz_mutex_leave(host->mutex); co->operation_timeout = operation_timeout; co->session_timeout = session_timeout;