Add potentially required barriers to TEnconding.

This commit is contained in:
Rika Ichinose 2023-11-10 00:22:46 +03:00
parent b6999496a7
commit ce1a82a1e4

View File

@ -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