thread safe FixPointer (without locking)

This commit is contained in:
Бондарев Иван 2020-02-25 20:46:33 +01:00
parent 36e42e42e1
commit 564ebf9799
2 changed files with 10 additions and 12 deletions

View file

@ -40,5 +40,4 @@ begin
p := @x[2];
p^.name := 'def';
assert(p^.name = 'def');
readln;
end.

View file

@ -12507,32 +12507,31 @@ begin
result := 0;
end;
type NotPinnableWrapper = class
[ThreadStatic]
static notPinnableTypes: HashSet<&Type>;
end;
// -----------------------------------------------------
// Internal procedures for PABCRTL.dll: implementation
// -----------------------------------------------------
var
__initialized := false;
nonPinnableLock := new object;
notPinnableTypes: HashSet<&Type>;
[System.Diagnostics.DebuggerStepThrough]
function __FixPointer(obj: object): GCHandle;
begin
if obj <> nil then
begin
try
if notPinnableTypes.Contains(obj.GetType()) then
if (NotPinnableWrapper.notPinnableTypes <> nil) and NotPinnableWrapper.notPinnableTypes.Contains(obj.GetType()) then
Result := GCHandle.Alloc(obj)
else
Result := GCHandle.Alloc(obj, GCHandleType.Pinned);
except
lock nonPinnableLock do
begin
if notPinnableTypes = nil then
notPinnableTypes := new HashSet<&Type>;
notPinnableTypes.Add(obj.GetType());
end;
if NotPinnableWrapper.notPinnableTypes = nil then
NotPinnableWrapper.notPinnableTypes := new HashSet<&Type>;
NotPinnableWrapper.notPinnableTypes.Add(obj.GetType());
Result := GCHandle.Alloc(obj);
end;
end;