Browse Source

* Make singletons thread-safe

git-svn-id: trunk@34483 -
michael 9 years ago
parent
commit
b504cc4131
2 changed files with 53 additions and 15 deletions
  1. 51 14
      rtl/objpas/sysutils/sysencoding.inc
  2. 2 1
      rtl/objpas/sysutils/sysencodingh.inc

+ 51 - 14
rtl/objpas/sysutils/sysencoding.inc

@@ -17,8 +17,13 @@
 
 
 class function TEncoding.GetANSI: TEncoding;
 class function TEncoding.GetANSI: TEncoding;
 begin
 begin
-  if not Assigned(FStandardEncodings[seAnsi]) then
-    FStandardEncodings[seAnsi] := TMBCSEncoding.Create(DefaultSystemCodePage);
+  EnterCriticalSection(FLock);
+  try
+    if not Assigned(FStandardEncodings[seAnsi]) then
+      FStandardEncodings[seAnsi] := TMBCSEncoding.Create(DefaultSystemCodePage);
+  finally
+    LeaveCriticalSection(FLock);
+  end;
   Result := FStandardEncodings[seAnsi];
   Result := FStandardEncodings[seAnsi];
 end;
 end;
 
 
@@ -47,15 +52,25 @@ end;
 
 
 class function TEncoding.GetASCII: TEncoding;
 class function TEncoding.GetASCII: TEncoding;
 begin
 begin
-  if not Assigned(FStandardEncodings[seAscii]) then
-    FStandardEncodings[seAscii] := TMBCSEncoding.Create(CP_ASCII);
+  EnterCriticalSection(FLock);
+  try
+    if not Assigned(FStandardEncodings[seAscii]) then
+      FStandardEncodings[seAscii] := TMBCSEncoding.Create(CP_ASCII);
+  finally
+    LeaveCriticalSection(FLock);
+  end;
   Result := FStandardEncodings[seAscii];
   Result := FStandardEncodings[seAscii];
 end;
 end;
 
 
 class function TEncoding.GetBigEndianUnicode: TEncoding;
 class function TEncoding.GetBigEndianUnicode: TEncoding;
 begin
 begin
-  if not Assigned(FStandardEncodings[seBigEndianUnicode]) then
-    FStandardEncodings[seBigEndianUnicode] := TBigEndianUnicodeEncoding.Create;
+  EnterCriticalSection(FLock);
+  try
+    if not Assigned(FStandardEncodings[seBigEndianUnicode]) then
+      FStandardEncodings[seBigEndianUnicode] := TBigEndianUnicodeEncoding.Create;
+  finally
+    LeaveCriticalSection(FLock);
+  end;
   Result := FStandardEncodings[seBigEndianUnicode];
   Result := FStandardEncodings[seBigEndianUnicode];
 end;
 end;
 
 
@@ -66,22 +81,37 @@ end;
 
 
 class function TEncoding.GetUnicode: TEncoding;
 class function TEncoding.GetUnicode: TEncoding;
 begin
 begin
-  if not Assigned(FStandardEncodings[seUnicode]) then
-    FStandardEncodings[seUnicode] := TUnicodeEncoding.Create;
+  EnterCriticalSection(FLock);
+  try
+    if not Assigned(FStandardEncodings[seUnicode]) then
+      FStandardEncodings[seUnicode] := TUnicodeEncoding.Create;
+  finally
+    LeaveCriticalSection(FLock);
+  end;
   Result := FStandardEncodings[seUnicode];
   Result := FStandardEncodings[seUnicode];
 end;
 end;
 
 
 class function TEncoding.GetUTF7: TEncoding;
 class function TEncoding.GetUTF7: TEncoding;
 begin
 begin
-  if not Assigned(FStandardEncodings[seUTF7]) then
-    FStandardEncodings[seUTF7] := TUTF7Encoding.Create;
+  EnterCriticalSection(FLock);
+  try
+    if not Assigned(FStandardEncodings[seUTF7]) then
+      FStandardEncodings[seUTF7] := TUTF7Encoding.Create;
+  finally
+    LeaveCriticalSection(FLock);
+  end;
   Result := FStandardEncodings[seUTF7];
   Result := FStandardEncodings[seUTF7];
 end;
 end;
 
 
 class function TEncoding.GetUTF8: TEncoding;
 class function TEncoding.GetUTF8: TEncoding;
 begin
 begin
-  if not Assigned(FStandardEncodings[seUTF8]) then
-    FStandardEncodings[seUTF8] := TUTF8Encoding.Create;
+  EnterCriticalSection(FLock);
+  try
+    if not Assigned(FStandardEncodings[seUTF8]) then
+      FStandardEncodings[seUTF8] := TUTF8Encoding.Create;
+  finally
+    LeaveCriticalSection(FLock);
+  end;
   Result := FStandardEncodings[seUTF8];
   Result := FStandardEncodings[seUTF8];
 end;
 end;
 
 
@@ -89,8 +119,13 @@ class procedure TEncoding.FreeEncodings;
 var
 var
   E: TStandardEncoding;
   E: TStandardEncoding;
 begin
 begin
-  for E := Low(FStandardEncodings) to High(FStandardEncodings) do
-    FStandardEncodings[E].Free;
+  EnterCriticalSection(FLock);
+  try
+    for E := Low(FStandardEncodings) to High(FStandardEncodings) do
+      FStandardEncodings[E].Free;
+  finally
+    LeaveCriticalSection(FLock);
+  end;
 end;
 end;
 
 
 class constructor TEncoding.Create;
 class constructor TEncoding.Create;
@@ -99,11 +134,13 @@ var
 begin
 begin
   for E := Low(FStandardEncodings) to High(FStandardEncodings) do
   for E := Low(FStandardEncodings) to High(FStandardEncodings) do
     FStandardEncodings[E] := nil;
     FStandardEncodings[E] := nil;
+  InitCriticalSection(FLock);
 end;
 end;
 
 
 class destructor TEncoding.Destroy;
 class destructor TEncoding.Destroy;
 begin
 begin
   FreeEncodings;
   FreeEncodings;
+  DoneCriticalSection(FLock);
 end;
 end;
 
 
 function TEncoding.Clone: TEncoding;
 function TEncoding.Clone: TEncoding;

+ 2 - 1
rtl/objpas/sysutils/sysencodingh.inc

@@ -30,7 +30,8 @@ type
         seUTF8);
         seUTF8);
     var
     var
       FStandardEncodings: array[TStandardEncoding] of TEncoding; static;
       FStandardEncodings: array[TStandardEncoding] of TEncoding; static;
-
+    Class Var
+      FLock : TRTLCriticalSection;
     class function GetANSI: TEncoding; static;
     class function GetANSI: TEncoding; static;
     class function GetASCII: TEncoding; static;
     class function GetASCII: TEncoding; static;
     class function GetBigEndianUnicode: TEncoding; static;
     class function GetBigEndianUnicode: TEncoding; static;