Browse Source

Add potentially required barriers to TEnconding.

Rika Ichinose 1 year ago
parent
commit
ce1a82a1e4
1 changed files with 10 additions and 0 deletions
  1. 10 0
      rtl/objpas/sysutils/sysencoding.inc

+ 10 - 0
rtl/objpas/sysutils/sysencoding.inc

@@ -19,10 +19,16 @@ class function TEncoding.GetStandard(Se: TStandardEncoding; Ctr: TCreateEncoding
 begin
 begin
   Result := FStandardEncodings[Se];
   Result := FStandardEncodings[Se];
   if Assigned(Result) then
   if Assigned(Result) then
+  begin
+{$ifdef FPC_HAS_FEATURE_THREADING}
+    ReadDependencyBarrier; // Read Result contents (by caller) after Result pointer.
+{$endif}
     Exit;
     Exit;
+  end;
 
 
   Result := Ctr();
   Result := Ctr();
 {$ifdef FPC_HAS_FEATURE_THREADING}
 {$ifdef FPC_HAS_FEATURE_THREADING}
+  WriteBarrier; // Write FStandardEncodings[Se] after Result contents.
   if InterlockedCompareExchange(Pointer(FStandardEncodings[Se]), Pointer(Result), nil) <> nil then
   if InterlockedCompareExchange(Pointer(FStandardEncodings[Se]), Pointer(Result), nil) <> nil then
   begin
   begin
     Result.Free;
     Result.Free;
@@ -110,6 +116,9 @@ begin
   repeat
   repeat
     Cp := DefaultSystemCodePage;
     Cp := DefaultSystemCodePage;
     Head := FSystemEncodingsList; // Must not be re-read until InterlockedCompareExchange to guarantee that search was performed against this head.
     Head := FSystemEncodingsList; // Must not be re-read until InterlockedCompareExchange to guarantee that search was performed against this head.
+{$ifdef FPC_HAS_FEATURE_THREADING}
+    ReadDependencyBarrier; // Read Head contents after Head pointer.
+{$endif}
     Result := Head;
     Result := Head;
     while Assigned(Result) do
     while Assigned(Result) do
       if Result.CodePage = Cp then
       if Result.CodePage = Cp then
@@ -121,6 +130,7 @@ begin
     Result := TMBCSEncoding.Create(Cp);
     Result := TMBCSEncoding.Create(Cp);
     Result.FNext := Head;
     Result.FNext := Head;
 {$ifdef FPC_HAS_FEATURE_THREADING}
 {$ifdef FPC_HAS_FEATURE_THREADING}
+    WriteBarrier; // Write FSystemEncodingsList after Result contents.
     if InterlockedCompareExchange(Pointer(FSystemEncodingsList), Pointer(Result), Pointer(Head)) = Pointer(Head) then
     if InterlockedCompareExchange(Pointer(FSystemEncodingsList), Pointer(Result), Pointer(Head)) = Pointer(Head) then
       break
       break
     else
     else