⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpwinsync.pas

📁 类似于Java JUnit的单元测试
💻 PAS
📖 第 1 页 / 共 3 页
字号:
    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 + -