📄 xpwinsync.pas
字号:
public
constructor Create;
end;
type TXPWinProcessRWSynchroniser = class(TSyncRWBase)
private
FName: string;
FReaders: IXPSharedCounter;
FAccess: IXPWinSynchro;
FBlockReaders: IXPWinSynchro;
protected
// Use ReadBegin/ReadEnd with a try..finally context
procedure ReadBegin; override;
procedure ReadEnd; override;
// Use WriteBegin/WriteEnd with a try..finally context
procedure WriteBegin; override;
procedure WriteEnd; override;
public
constructor Create(const Name: string; const Inheritable: boolean;
const SecurityDescriptor: Pointer);
end;
// "Readers and writers" implementation (2)
//
// Single writer and multiple (unlimited) readers
// Priority given to writers, ie no more readers allowed once a writer
// is waiting, and waiting writers given priority over waiting readers.
// ( Can lead to reader starvation. )
// Implementation uses critical sections and is therefore limited
// to a single process.
type TXPWinThreadWRSynchroniser = class(TSyncRWBase)
private
FReaders: integer;
FWriters: integer;
FAccess: IXPWinSynchro;
FQueueReader: IXPWinSynchro;
FBlockReaders: IXPWinSynchro;
FRMutex: IXPWinSynchro;
FWMutex: IXPWinSynchro;
protected
// Use ReadBegin/ReadEnd with a try..finally context
procedure ReadBegin; override;
procedure ReadEnd; override;
// Use WriteBegin/WriteEnd with a try..finally context
procedure WriteBegin; override;
procedure WriteEnd; override;
public
constructor Create;
end;
type TXPWinProcessWRSynchroniser = class(TSyncRWBase)
private
FReaders: IXPSharedCounter;
FWriters: IXPSharedCounter;
FName: string;
FAccess: IXPWinSynchro;
FBlockReaders: IXPWinSynchro;
protected
// Use ReadBegin/ReadEnd with a try..finally context
procedure ReadBegin; override;
procedure ReadEnd; override;
// Use WriteBegin/WriteEnd with a try..finally context
procedure WriteBegin; override;
procedure WriteEnd; override;
public
constructor Create(const Name: string; const Inheritable: boolean;
const SecurityDescriptor: Pointer);
end;
/////////////////////////////////////////////////////////////////////////////
// TThreadSyncRW implementation
// Based on: Courtois et al, Communications of the ACM,
// Vol 14, No 10 Oct 1971, pp. 667-668
/////////////////////////////////////////////////////////////////////////////
constructor TXPWinThreadRWSynchroniser.Create;
begin
inherited Create;
FAccess := XPWinSync.CreateCriticalSection;
FMutex := XPWinSync.CreateCriticalSection;
end;
procedure TXPWinThreadRWSynchroniser.ReadBegin;
begin
FMutex.Enter;
try
System.Inc(FReaders);
if FReaders = 1 then
FAccess.Enter;
finally
FMutex.Leave;
end;
end;
procedure TXPWinThreadRWSynchroniser.ReadEnd;
begin
FMutex.Enter;
try
System.Dec(FReaders);
if FReaders = 0 then
FAccess.Leave;
finally
FMutex.Leave;
end;
end;
procedure TXPWinThreadRWSynchroniser.WriteBegin;
begin
FAccess.Enter;
end;
procedure TXPWinThreadRWSynchroniser.WriteEnd;
begin
FAccess.Leave;
end;
/////////////////////////////////////////////////////////////////////////////
// TProcessSyncRW implementation
/////////////////////////////////////////////////////////////////////////////
constructor TXPWinProcessRWSynchroniser.Create(const Name: string;
const Inheritable: boolean; const SecurityDescriptor: Pointer);
begin
inherited Create;
FName := Name;
FReaders := XPWinSync.GetSharedCounter(0, FName + '.FReaders', Inheritable,
SecurityDescriptor);
FAccess := XPWinSync.GetMutex(FName + '.FAccess', Inheritable,
SecurityDescriptor) as IXPWinSynchro;
FBlockReaders := XPWinSync.GetMutex(FName + '.FMutex', Inheritable,
SecurityDescriptor) as IXPWinSynchro;
end;
procedure TXPWinProcessRWSynchroniser.ReadBegin;
begin
FBlockReaders.Enter;
try
if FReaders.Inc = 1 then
FAccess.Enter;
finally
FBlockReaders.Leave;
end;
end;
procedure TXPWinProcessRWSynchroniser.ReadEnd;
begin
if FReaders.Dec = 0 then
FAccess.Leave;
end;
procedure TXPWinProcessRWSynchroniser.WriteBegin;
begin
FAccess.Enter;
end;
procedure TXPWinProcessRWSynchroniser.WriteEnd;
begin
FAccess.Leave;
end;
/////////////////////////////////////////////////////////////////////////////
// TThreadSyncWR implementation
// Based on: Courtois et al, Communications of the ACM,
// Vol 14, No 10 Oct 1971, pp. 667-668
/////////////////////////////////////////////////////////////////////////////
constructor TXPWinThreadWRSynchroniser.Create;
begin
inherited Create;
FAccess := XPWinSync.CreateCriticalSection;
FQueueReader := XPWinSync.CreateCriticalSection;
FBlockReaders := XPWinSync.CreateCriticalSection;
FRMutex := XPWinSync.CreateCriticalSection;
FWMutex := XPWinSync.CreateCriticalSection;
end;
procedure TXPWinThreadWRSynchroniser.ReadBegin;
begin
FQueueReader.Enter;
try
FBlockReaders.Enter;
try
FRMutex.Enter;
try
System.Inc(FReaders);
if FReaders = 1 then
FAccess.Enter;
finally
FRMutex.Leave;
end;
finally
FBlockReaders.Leave;
end;
finally
FQueueReader.Leave;
end;
end;
procedure TXPWinThreadWRSynchroniser.ReadEnd;
begin
FRMutex.Enter;
try
System.Dec(FReaders);
if FReaders = 0 then
FAccess.Leave;
finally
FRMutex.Leave;
end;
end;
procedure TXPWinThreadWRSynchroniser.WriteBegin;
begin
FWMutex.Enter;
try
System.Inc(FWriters);
if (FWriters = 1) then
FBlockReaders.Enter;
finally
FWMutex.Leave;
end;
FAccess.Enter;
end;
procedure TXPWinThreadWRSynchroniser.WriteEnd;
begin
FAccess.Leave;
FWMutex.Enter;
try
System.Dec(FWriters);
if FWriters = 0 then
FBlockReaders.Leave;
finally
FWMutex.Leave;
end;
end;
/////////////////////////////////////////////////////////////////////////////
// TProcessSyncWR implementation
/////////////////////////////////////////////////////////////////////////////
constructor TXPWinProcessWRSynchroniser.Create(const Name: string;
const Inheritable: boolean; const SecurityDescriptor: Pointer);
const
InitialValue = 0;
begin
inherited Create;
FName := Name;
FReaders := XPWinSync.GetSharedCounter(InitialValue, FName + '.FReaders',
Inheritable, SecurityDescriptor);
FWriters := XPWinSync.GetSharedCounter(InitialValue, FName + '.FWriters',
Inheritable, SecurityDescriptor);
FAccess := XPWinSync.GetMutex(FName + '.FAccess', Inheritable,
SecurityDescriptor) as IXPWinSynchro;
FBlockReaders := XPWinSync.GetMutex(FName + '.FBlockReaders', Inheritable,
SecurityDescriptor) as IXPWinSynchro;
end;
procedure TXPWinProcessWRSynchroniser.ReadBegin;
begin
FBlockReaders.Enter;
try
if FReaders.Inc = 1 then
FAccess.Enter;
finally
FBlockReaders.Leave;
end;
end;
procedure TXPWinProcessWRSynchroniser.ReadEnd;
begin
if FReaders.Dec = 0 then
FAccess.Leave;
end;
procedure TXPWinProcessWRSynchroniser.WriteBegin;
begin
if FWriters.Inc = 1 then
FBlockReaders.Enter;
FAccess.Enter;
end;
procedure TXPWinProcessWRSynchroniser.WriteEnd;
begin
FAccess.Leave;
if FWriters.Dec = 0 then
FBlockReaders.Leave;
end;
///////////////////////////////////////////////////////////////////////////////
/// Global functions
///////////////////////////////////////////////////////////////////////////////
function GetAutoEvent(const CreateAsSignaled: boolean;
const AName: string; const Inheritable: boolean;
const SecurityDescriptor: Pointer): IXPWinAutoEvent;
begin
Result := TXPWinAutoEvent.Create(AName, CreateAsSignaled, Inheritable,
SecurityDescriptor);
end;
function GetManualEvent(const CreateAsSignaled: boolean;
const AName: string; const Inheritable: boolean;
const SecurityDescriptor: Pointer): IXPWinManualEvent;
begin
Result := TXPWinManualEvent.Create(AName, CreateAsSignaled, Inheritable,
SecurityDescriptor);
end;
function GetMutex(const AName: string; const Inheritable: boolean;
const SecurityDescriptor: Pointer): IXPWinMutex;
begin
Result := TXPWinMutex.Create(AName, Inheritable, SecurityDescriptor);
end;
function GetSemaphore(const Capacity: integer; const AName: string;
const CreateOpen: boolean; const Inheritable: boolean;
const SecurityDescriptor: Pointer): IXPWinSemaphore;
begin
Result := TXPWinSemaphore.Create(Capacity, AName, CreateOpen, Inheritable,
SecurityDescriptor);
end;
function CreateCriticalSection: IXPWinSynchro;
begin
Result := TXPWinCriticalSection.Create;
end;
function GetSharedCounter(const InitialValue: integer;
const AName: string; const Inheritable: boolean;
const SecurityDescriptor: Pointer): IXPSharedCounter;
begin
Result := TXPWinSharedCounter.Create(InitialValue, AName, Inheritable,
SecurityDescriptor);
end;
function CreateThreadRWSynchroniser(
const SyncPriority: TXPSyncPriority): IXPSyncRW;
begin
if SyncPriority = spWriters then
Result := TXPWinThreadWRSynchroniser.Create
else
Result := TXPWinThreadRWSynchroniser.Create;
end;
function GetProcessRWSynchroniser(const Name: string;
const SyncPriority: TXPSyncPriority; const Inheritable: boolean;
const SecurityDescriptor: Pointer): IXPSyncRW;
begin
if SyncPriority = spWriters then
Result := TXPWinProcessWRSynchroniser.Create(Name, Inheritable,
SecurityDescriptor)
else
Result := TXPWinProcessRWSynchroniser.Create(Name, Inheritable,
SecurityDescriptor);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -