|
@@ -408,7 +408,6 @@ var
|
|
_oldMonitor,
|
|
_oldMonitor,
|
|
_monitor : TMonitorManager;
|
|
_monitor : TMonitorManager;
|
|
_DummySpinCount : Integer;
|
|
_DummySpinCount : Integer;
|
|
- _MemLock : TRTLCriticalSection;
|
|
|
|
|
|
|
|
function GetMonitorData(aObject : TObject) : PMonitorData; inline;
|
|
function GetMonitorData(aObject : TObject) : PMonitorData; inline;
|
|
|
|
|
|
@@ -416,28 +415,31 @@ begin
|
|
Result:=PMonitorData(_monitor.DoGetMonitorObjectData(aObject));
|
|
Result:=PMonitorData(_monitor.DoGetMonitorObjectData(aObject));
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure SetMonitorData(aObject : TObject; aData : PMonitorData); inline;
|
|
|
|
|
|
+function SetMonitorData(aObject : TObject; aData,aComparand : PMonitorData) : PMonitorData; inline;
|
|
|
|
|
|
begin
|
|
begin
|
|
- _monitor.DoSetMonitorObjectData(aObject,aData);
|
|
|
|
|
|
+ Result:=_monitor.DoSetMonitorObjectData(aObject,aData,aComparand);
|
|
end;
|
|
end;
|
|
|
|
|
|
function SyncEnsureData(aObject : TObject) : PMonitorData;
|
|
function SyncEnsureData(aObject : TObject) : PMonitorData;
|
|
|
|
|
|
begin
|
|
begin
|
|
- EnterCriticalSection(_MemLock);
|
|
|
|
- try
|
|
|
|
|
|
+ repeat
|
|
Result:=GetMonitorData(aObject);
|
|
Result:=GetMonitorData(aObject);
|
|
- if Result=Nil then
|
|
|
|
|
|
+ if Result<>Nil then
|
|
begin
|
|
begin
|
|
- // At some point we could cache this.
|
|
|
|
- New(Result);
|
|
|
|
- Result^.Init;
|
|
|
|
- SetMonitorData(aObject,Result);
|
|
|
|
|
|
+ ReadDependencyBarrier; // Read Result fields after Result pointer.
|
|
|
|
+ exit;
|
|
end;
|
|
end;
|
|
- finally
|
|
|
|
- LeaveCriticalSection(_MemLock);
|
|
|
|
- end;
|
|
|
|
|
|
+
|
|
|
|
+ // At some point we could cache this.
|
|
|
|
+ New(Result);
|
|
|
|
+ Result^.Init;
|
|
|
|
+ WriteBarrier; // Write pointer with SetMonitorData only after Result fields have been written.
|
|
|
|
+ if SetMonitorData(aObject,Result,nil)=nil then
|
|
|
|
+ break;
|
|
|
|
+ Dispose(Result); // And retry GetMonitorData + ReadDependencyBarrier from the beginning of the loop, which will guaranteedly succeed.
|
|
|
|
+ until false;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure SyncFreeData(aData : PMonitorData);
|
|
procedure SyncFreeData(aData : PMonitorData);
|
|
@@ -549,7 +551,6 @@ end;
|
|
procedure RegisterMonitorSupport;
|
|
procedure RegisterMonitorSupport;
|
|
|
|
|
|
begin
|
|
begin
|
|
- InitCriticalSection(_MemLock);
|
|
|
|
InitMonitorSupport;
|
|
InitMonitorSupport;
|
|
_OldMonitor:=SetMonitorManager(_Monitor);
|
|
_OldMonitor:=SetMonitorManager(_Monitor);
|
|
end;
|
|
end;
|
|
@@ -557,7 +558,6 @@ end;
|
|
procedure UnRegisterMonitorSupport;
|
|
procedure UnRegisterMonitorSupport;
|
|
|
|
|
|
begin
|
|
begin
|
|
- DoneCriticalSection(_MemLock);
|
|
|
|
SetMonitorManager(_oldMonitor);
|
|
SetMonitorManager(_oldMonitor);
|
|
end;
|
|
end;
|
|
|
|
|