X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fconnection.c;h=7913651c58bb71efbc7e4b88cd7f94a2d9151a72;hb=c42c5fe8bef789267f4a3f0822480ef0477b4b74;hp=fecf51b9fd7f4a04278ae7f5e32f64cdfb1704d9;hpb=b73890ede1ee6eeb8a07937733871077df6f15b9;p=pazpar2-moved-to-github.git diff --git a/src/connection.c b/src/connection.c index fecf51b..7913651 100644 --- a/src/connection.c +++ b/src/connection.c @@ -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,6 +147,12 @@ 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; } @@ -173,7 +172,6 @@ static void non_block_events(struct connection *co) continue; ev = ZOOM_connection_last_event(link); - client_incref(cl); #if 0 yaz_log(YLOG_LOG, "ZOOM_EVENT_%s", ZOOM_get_event_str(ev)); #endif @@ -220,64 +218,77 @@ static void non_block_events(struct connection *co) yaz_log(YLOG_LOG, "Unhandled event (%d) from %s", ev, client_get_url(cl)); } - client_destroy(cl); } if (got_records) { struct client *cl = co->client; if (cl) { - client_incref(cl); client_got_records(cl); - client_destroy(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; @@ -428,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, @@ -475,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;