From: Zdeněk Šustr Date: Thu, 5 Oct 2006 13:43:15 +0000 (+0000) Subject: onnection pool repairs - pool overflows solved (at least partially) X-Git-Tag: merge_connpool_src~10 X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=fc2ee89a05434ca23a9722c8b78083f03b79361f;p=jra1mw.git onnection pool repairs - pool overflows solved (at least partially) --- diff --git a/org.glite.lb.client/src/connection.c b/org.glite.lb.client/src/connection.c index 17a7560..620eaa4 100644 --- a/org.glite.lb.client/src/connection.c +++ b/org.glite.lb.client/src/connection.c @@ -117,9 +117,9 @@ static int AddConnection(edg_wll_Context ctx, char *name, int port) -static void ReleaseConnection(edg_wll_Context ctx, char *name, int port) +static int ReleaseConnection(edg_wll_Context ctx, char *name, int port) { - int i, index = 0; + int i, index = 0, foundConnToDrop = 0; long min; @@ -130,17 +130,31 @@ static void ReleaseConnection(edg_wll_Context ctx, char *name, int port) CloseConnection(ctx, &index); } else { /* free the oldest (unlocked) connection */ - assert(ctx->connections->connPool[0].peerName); // Full pool expected - accept non-NULL values only - min = ctx->connections->connPool[0].lastUsed.tv_sec; +/* assert(ctx->connections->connPool[0].peerName); // Full pool expected - accept non-NULL values only + min = ctx->connections->connPool[0].lastUsed.tv_sec;*/ for (i=0; iconnections->poolSize; i++) { assert(ctx->connections->connPool[i].peerName); // Full pool expected - accept non-NULL values only - if (ctx->connections->connPool[i].lastUsed.tv_sec < min) { - min = ctx->connections->connPool[i].lastUsed.tv_sec; - index = i; + if (!edg_wll_connectionTryLock(ctx, i)) { + edg_wll_connectionUnlock(ctx, i); // Connection unlocked. Consider releasing it + if (foundConnToDrop) { // This is not the first unlocked connection + if (ctx->connections->connPool[i].lastUsed.tv_sec < min) { + min = ctx->connections->connPool[i].lastUsed.tv_sec; + index = i; + foundConnToDrop++; + } + } + else { // This is the first unlocked connection we have found. + foundConnToDrop++; + index = i; + min = ctx->connections->connPool[i].lastUsed.tv_sec; + } } } +// printf("Connections to drop: %d\nDropping connection No. %d\n",foundConnToDrop,index); + if (!foundConnToDrop) return edg_wll_SetError(ctx,EAGAIN,"all connections in the connection pool are locked"); CloseConnection(ctx, &index); } + return edg_wll_Error(ctx,NULL,NULL); } @@ -182,10 +196,13 @@ int edg_wll_open(edg_wll_Context ctx, int* connToUse) if ( (index = ConnectionIndex(ctx, ctx->srvName, ctx->srvPort)) == -1 ) { /* no such open connection in pool */ if (ctx->connections->connOpened == ctx->connections->poolSize) - ReleaseConnection(ctx, NULL, 0); + if(ReleaseConnection(ctx, NULL, 0)) goto end; index = AddConnection(ctx, ctx->srvName, ctx->srvPort); - if (index < 0) return edg_wll_SetError(ctx,EAGAIN,"connection pool size exceeded"); + if (index < 0) { + edg_wll_SetError(ctx,EAGAIN,"connection pool size exceeded"); + goto end; + } #ifdef EDG_WLL_CONNPOOL_DEBUG printf("Connection to %s:%d opened as No. %d in the pool\n",ctx->srvName,ctx->srvPort,index); @@ -248,12 +265,14 @@ int edg_wll_open(edg_wll_Context ctx, int* connToUse) err: /* some error occured; close created connection * and free all fields in connPool[index] */ - CloseConnection(ctx, &index); + if (index >= 0) CloseConnection(ctx, &index); *connToUse = -1; ok: if (*connToUse>-1) edg_wll_connectionTryLock(ctx, *connToUse); /* Just to be sure we have not forgotten to lock it */ +end: + edg_wll_poolUnlock(); /* One way or the other, there are no more pool-wide operations */ // xxxxx @@ -375,6 +394,8 @@ int edg_wll_http_send_recv( int connToUse = -1; //Index of the connection to use. Used to be a context member. if (edg_wll_open(ctx,&connToUse)) return edg_wll_Error(ctx,NULL,NULL); + + edg_wll_connectionTryLock(ctx, connToUse); switch (edg_wll_http_send(ctx,request,req_head,req_body,&ctx->connections->connPool[connToUse])) { case ENOTCONN: @@ -401,6 +422,9 @@ int edg_wll_http_send_recv( assert(connToUse >= 0); gettimeofday(&ctx->connections->connPool[connToUse].lastUsed, NULL); + + sleep(3); //Just for testing + edg_wll_connectionUnlock(ctx, connToUse); return 0;