瀏覽代碼

* Reworked pool to a thread list

git-svn-id: trunk@25249 -
michael 12 年之前
父節點
當前提交
abae19b553
共有 1 個文件被更改,包括 58 次插入46 次删除
  1. 58 46
      packages/fcl-db/src/sqldb/postgres/pqconnection.pp

+ 58 - 46
packages/fcl-db/src/sqldb/postgres/pqconnection.pp

@@ -50,12 +50,11 @@ type
 
   TPQConnection = class (TSQLConnection)
   private
-    FConnectionPool      : array of TPQTranConnection;
+    FConnectionPool      : TThreadList;
     FCursorCount         : dword;
     FConnectString       : string;
     FIntegerDateTimes    : boolean;
     FVerboseErrors       : Boolean;
-    FPool : TRTLCriticalSection;
     procedure CheckConnectionStatus(var conn: PPGconn);
     procedure CheckResultError(var res: PPGresult; conn:PPGconn; ErrMsg: string);
     function TranslateFldType(res : PPGresult; Tuple : integer; out Size : integer) : TFieldType;
@@ -167,12 +166,12 @@ begin
   FConnOptions := FConnOptions + [sqSupportParams] + [sqEscapeRepeat] + [sqEscapeSlash];
   FieldNameQuoteChars:=DoubleQuotes;
   VerboseErrors:=True;
-  InitCriticalSection(FPool);
+  FConnectionPool:=TThreadlist.Create;
 end;
 
 destructor TPQConnection.destroy;
 begin
-  DoneCriticalSection(FPool);
+  FreeAndNil(FConnectionPool);
   inherited destroy;
 end;
 
@@ -223,41 +222,34 @@ end;
 
 procedure TPQConnection.AddConnection(T: TPQTranConnection);
 
-Var
-  I : Integer;
-
 begin
-  // make connection available in pool
-  EnterCriticalSection(FPool);
-  try
-    I:=Length(FConnectionPool);
-    SetLength(FConnectionPool,I+1);
-    FConnectionPool[i]:=T;
-  finally
-    EnterCriticalSection(FPool);
-  end;
+  FConnectionPool.Add(T);
 end;
 
 procedure TPQConnection.ReleaseConnection(Conn: PPGConn; DoClear: Boolean);
 
 Var
   I : Integer;
+  L : TList;
+  T : TPQTranConnection;
 
 begin
+  L:=FConnectionPool.LockList;
   // make connection available in pool
-  EnterCriticalSection(FPool);
   try
-    for i:=0 to length(FConnectionPool)-1 do
-      if (FConnectionPool[i].FPGConn=Conn) then
+    for i:=0 to L.Count-1 do
+      begin
+      T:=TPQTranConnection(L[i]);
+      if (T.FPGConn=Conn) then
         begin
-
-        FConnectionPool[i].FTranActive:=false;
+        T.FTranActive:=false;
         if DoClear then
-          FConnectionPool[i].FPGConn:=Nil;
-          break;
+          T.FPGConn:=Nil;
+        break;
         end;
+      end
   finally
-    EnterCriticalSection(FPool);
+    FConnectionPool.UnlockList;
   end;
 end;
 
@@ -311,17 +303,19 @@ var
   tr  : TPQTrans;
   i   : Integer;
   t : TPQTranConnection;
+  L : TList;
 begin
   result:=false;
   tr := trans as TPQTrans;
 
   //find an unused connection in the pool
   i:=0;
-  EnterCriticalSection(FPool);
+  t:=Nil;
+  L:=FConnectionPool.LockList;
   try
-    while i<length(FConnectionPool) do
+    while (I<L.Count-1) do
       begin
-      T:=FConnectionPool[i];
+      T:=TPQTranConnection(L[i]);
       if (T.FPGConn=nil) or not T.FTranActive then
         break
       else
@@ -333,7 +327,7 @@ begin
     if Assigned(T) then
       T.FTranActive:=true;
   finally
-    LeaveCriticalSection(FPool);
+    FConnectionPool.UnLockList;
   end;
   if (T=Nil) then
     begin
@@ -428,20 +422,25 @@ begin
 end;
 
 procedure TPQConnection.DoInternalDisconnect;
-var i:integer;
+var
+  i:integer;
+  L : TList;
+  T : TPQTranConnection;
+
 begin
   Inherited;
-  EnterCriticalSection(FPool);
+  L:=FConnectionPool.LockList;
   try
-    for i:=0 to length(FConnectionPool)-1 do
+    for i:=0 to L.Count-1 do
       begin
-      if assigned(FConnectionPool[i].FPGConn) then
-        PQfinish(FConnectionPool[i].FPGConn);
-      FConnectionPool[i].Free;
+      T:=TPQTranConnection(L[i]);
+      if assigned(T.FPGConn) then
+        PQfinish(T.FPGConn);
+      T.Free;
       end;
-    Setlength(FConnectionPool,0);
+    L.Clear;
   finally
-    LeaveCriticalSection(FPool);
+    FConnectionPool.UnLockList;
   end;
 {$IfDef LinkDynamically}
   ReleasePostgres3;
@@ -863,26 +862,39 @@ end;
 function TPQConnection.GetHandle: pointer;
 var
   i:integer;
+  L : TList;
+  T : TPQTranConnection;
+
 begin
   result:=nil;
   if not Connected then
     exit;
   //Get any handle that is (still) connected
-  for i:=0 to length(FConnectionPool)-1 do
-    if assigned(FConnectionPool[i].FPGConn) and (PQstatus(FConnectionPool[i].FPGConn)<>CONNECTION_BAD) then
+  L:=FConnectionPool.LockList;
+  try
+    I:=L.Count-1;
+    While (I>=0) and (Result=Nil) do
       begin
-      Result :=FConnectionPool[i].FPGConn;
-      exit;
+      T:=TPQTranConnection(L[i]);
+      if assigned(T.FPGConn) and (PQstatus(T.FPGConn)<>CONNECTION_BAD) then
+        Result:=T.FPGConn;
+      Dec(I);
       end;
+  finally
+    FConnectionPool.UnLockList;
+  end;
+  if Result<>Nil then
+     exit;
   //Nothing connected!! Reconnect
-  if assigned(FConnectionPool[0].FPGConn) then
-    PQreset(FConnectionPool[0].FPGConn)
+  // T is element 0 after loop
+  if assigned(T.FPGConn) then
+    PQreset(T.FPGConn)
   else
-    FConnectionPool[0].FPGConn := PQconnectdb(pchar(FConnectString));
-  CheckConnectionStatus(FConnectionPool[0].FPGConn);
+    T.FPGConn := PQconnectdb(pchar(FConnectString));
+  CheckConnectionStatus(T.FPGConn);
   if CharSet <> '' then
-    PQsetClientEncoding(FConnectionPool[0].FPGConn, pchar(CharSet));
-  result:=FConnectionPool[0].FPGConn;
+    PQsetClientEncoding(T.FPGConn, pchar(CharSet));
+  result:=T.FPGConn;
 end;
 
 function TPQConnection.Fetch(cursor : TSQLCursor) : boolean;