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

📄 unaclasses.pas

📁 Voice Commnucation Components for Delphi
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    function lock(): int;
    procedure unlock();
    //
    property data: pointer read f_data;
  end;


  //
  // -- unaMappedMemory --
  //

  {DP:CLASS
    This is wrapper class for the Windows mapped memory mechanism.
  }
  unaMappedMemory = class(unaObject)
  private
    f_doOpen: bool;
    f_access: DWORD;
    f_canCreate: bool;
    f_handle: tHandle;
    f_name: wideString;
    f_data: pArray;
    f_size: unsigned;
    f_fileHandle: tHandle;
    //
    procedure setSize(value: unsigned);
  protected
    function open2(access: DWORD = PAGE_READWRITE): bool; virtual;
    procedure close2(); virtual;
    procedure doSetNewSize(newValue: unsigned); virtual;
  public
    constructor create(const name: wideString; size: unsigned = 0; access: DWORD = PAGE_READWRITE; doOpen: bool = true; canCreate: bool = true);
    procedure AfterConstruction(); override;
    procedure BeforeDestruction(); override;
    //
    function open(access: DWORD = PAGE_READWRITE): bool;
    procedure close();
    //
    function read(buf: pointer; sz: unsigned): unsigned;
    function write(buf: pointer; sz: unsigned): unsigned;
    function flush(): bool;
    function getDataPtr(offset: unsigned): pointer;
    //
    property data: pArray read f_data;
    property size: unsigned read f_size write setSize;
    property handle: tHandle read f_handle;
  end;


  //
  // -- unaMappedFile --
  //

  {DP:CLASS
    This is wrapper class for the Windows mapped files mechanism.
  }
  unaMappedFile = class(unaMappedMemory)
  private
    f_fileName: wideString;
  protected
    function open2(access: DWORD = PAGE_READWRITE): bool; override;
    procedure close2(); override;
  public
    constructor create(const fileName: wideString; access: DWORD = PAGE_READWRITE; doOpen: bool = true; size: int = 0);
    //
    function openFile(const fileName: wideString; access: DWORD = PAGE_READWRITE; size: int = 0): bool;
    //
    function ensureSize(value: int): bool;
  end;


  //
  // -- unaConsoleApp --
  //

  {DP:CLASS
    This class encapsulates basic Windows console application.
  }
  unaConsoleApp = class(unaThread)
  private
    f_ok: bool;
    f_consoleInfo: CONSOLE_SCREEN_BUFFER_INFO;
    f_inHandle: tHandle;
    f_outHandle: tHandle;
    //
    function getConsoleInfo(): pConsoleScreenBufferInfo;
  protected
    f_executeComplete: bool;
    //
    {DP:METHOD
      You can override this method to perform additional initialization.
      <BR />If this method returns false the application will not be started.
    }
    function doInit(): bool; virtual;
    {DP:METHOD
      Processes Windows messages until the thread terminates.
    }
    function execute(globalIndex: unsigned): int; override;
  public
    {DP:METHOD
      Creates console application class. You can specify caption, icon and text attributes to be used in the console box initialization.
    }
    constructor create(const caption: wideString = ''; icon: hIcon = 0; textAttribute: unsigned = FOREGROUND_BLUE or FOREGROUND_RED or FOREGROUND_GREEN or FOREGROUND_INTENSITY);
    destructor Destroy(); override;
    procedure AfterConstruction(); override;
    //
    {DP:METHOD
      Starts the application thread. This method returns only when user press the Enter key.
    }
    procedure run(enterStop: bool = true);
    //
    property consoleInfo: pConsoleScreenBufferInfo read getConsoleInfo;
    property outputHandle: tHandle read f_outHandle;
    property inputHandle: tHandle read f_inHandle;
  end;



{DP:METHOD
  Locks list if it is not nil and contains at least one element.
  list.Unlock() must be called if this function returns true.
}
function lockNonEmptyList(list: unaList; timeout: unsigned = INFINITE): bool;

{DP:METHOD
  Returns true if files' content is the same.
  Uses mapped file class.
}
function sameFiles(const fileName1, fileName2: wideString): bool;

{}
function getFolderSize(const folder: wideString; includeSubFolders: bool = true): int64;


implementation


uses
  Messages;



{ unaObject }

// --  --
procedure unaObject.AfterConstruction();
begin
  assert(f_inheritedCreateWasCalled, _classID + ' inherited create() was not called!');
  //
  inherited;
end;

// --  --
constructor unaObject.create();
begin
  f_inheritedCreateWasCalled := true;
end;

// --  --
function unaObject.getClassID(): string;
begin
  {$IFDEF DEBUG }
  result := className;
  {$ELSE }
  result := '';
  {$ENDIF }
  //
  result := result + '[$' + int2str(uint(self), 16) + ']'
end;

// --  --
function unaObject.getThis(): unaObject;
begin
  result := self;	// self is not this! :)
end;


{ unaEvent }

// --  --
constructor unaEvent.create(manualReset, initialState: bool; const name: wideString);
begin
  inherited create();
  //
  f_name := name;
  //
  if (g_wideApiSupported) then
    //
    f_handle := CreateEventW(nil, manualReset, initialState, pWideChar(f_name))
  else
    f_handle := CreateEventA(nil, manualReset, initialState, pChar(string(f_name)));
  //
end;

// --  --
destructor unaEvent.Destroy();
begin
  inherited;
  //
  CloseHandle(f_handle);
end;

// --  --
procedure unaEvent.setState(signaled: bool);
begin
  if (signaled) then
    SetEvent(f_handle)
  else
    ResetEvent(f_handle);
end;

// --  --
function unaEvent.waitFor(timeout: unsigned): bool;
begin
  result := waitForObject(f_handle, timeout);
end;

{ unaAbstractGate }

// --  --
constructor unaAbstractGate.create({$IFDEF DEBUG}const title: string{$ENDIF});
begin
{$IFDEF DEBUG}
  f_title := title;
{$ENDIF}
  //
{$IFDEF UNA_GATE_PROFILE}
  f_profileIndex := profileMarkRegister(_classID + '(' + title + ')', unsigned(self));
{$ENDIF}
  //
  inherited create();
end;

// --  --
function unaAbstractGate.enter(timeout: unsigned{$IFDEF DEBUG}; const masterName: string{$ENDIF}): bool;
{$IFDEF DEBUG }
var
{$ELSE }
  {$IFDEF UNA_GATE_DEBUG_TIMEOUT }
var
  {$ENDIF }
{$ENDIF }

{$IFDEF UNA_GATE_DEBUG_TIMEOUT }
  mark: int64;
{$ENDIF}
{$IFDEF DEBUG }
  owner: unsigned;
  TLC, RLC: int;
{$ENDIF }
begin
  if (nil = self) then begin
    //
    assert(false, {$IFDEF DEBUG}'(' + masterName + ')' + {$ENDIF}'.enter(' + int2str(timeout) + ') - self is nil!');
    //
    result := false;
    exit;
  end;
  //
  if (INFINITE = timeout) then
    assert(assertLog(self._classID{$IFDEF DEBUG} + '(' + masterName + ')'{$ENDIF} + '.enter(' + int2str(timeout) + ') - INFINITE.'));
  //
{$IFDEF UNA_GATE_DEBUG_TIMEOUT }
  mark := timeMark();
{$ENDIF}
{$IFDEF DEBUG }
  if (self is unaInProcessGate) then begin
    //
    owner := (self as unaInProcessGate).owningThreadId;
    TLC := (self as unaInProcessGate).tryLockCount;
    RLC := (self as unaInProcessGate).recursionLockCount;
  end
  else begin
    //
    owner := unsigned(-1);
    TLC := -1;
    RLC := -1;
  end;
{$ENDIF }
  //
  result := gateEnter(timeout{$IFDEF DEBUG}, masterName{$ENDIF});
{$IFDEF UNA_GATE_DEBUG_TIMEOUT }
  logMessage({$IFDEF DEBUG}'(' + masterName + ')' + {$ENDIF}'.enter(' + int2str(timeout) + ') takes ' + int2str(timeElapsed64(mark), 10, 3));
{$ENDIF}
  //
  if (not result and (1 < timeout)) then begin
    //
    {$IFDEF DEBUG }
    assert(assertLog({$IFDEF DEBUG}self._classID + '(' + masterName + ').enter(timeout=' + int2str(timeout) + 'ms) ' + {$ENDIF}' gate is locked by [' + int2str(owner, 16) + ']; RLC=' + int2str(RLC) + '; TLC=' + int2str(TLC)));
    {$ENDIF }
    //
  end;
end;

// --  --
function unaAbstractGate.gateEnter(timeout: unsigned{$IFDEF DEBUG}; const masterName: string{$ENDIF}): bool;
begin
{$IFDEF DEBUG}
  f_masterName := masterName;
{$ENDIF}
  result := true;
end;

// --  --
procedure unaAbstractGate.gateLeave();
begin
{$IFDEF DEBUG}
  f_masterName := '';
{$ENDIF}
  f_isBusy := false;
end;

// --  --
procedure unaAbstractGate.leave();
begin
  gateLeave();
end;

{ unaOutProcessGate }

// --  --
function unaOutProcessGate.checkDeadlock(timeout: unsigned; const name: string): bool;
var
  ct: tHandle;
begin
  // simple deadlock check (seems not working properly / 10 Feb 2002)
  ct := GetCurrentThread();
  //
  if ((INFINITE = timeout) and f_inside and (f_masterThread = ct)) then begin
    result := true;
    assert(false, self._classID + '.enter(' + name + ') - potential deadlock');
  end
  else
    result := false;
end;

// --  --
constructor unaOutProcessGate.create({$IFDEF DEBUG}const title: string{$ENDIF});
begin
  inherited create({$IFDEF DEBUG}title{$ENDIF});
  //
  f_event := unaEvent.create(false, true);
end;

// --  --
destructor unaOutProcessGate.Destroy();
begin
  inherited;
  //
  leave();
  freeAndNil(f_event);
end;

// --  --
function unaOutProcessGate.gateEnter(timeout: unsigned{$IFDEF DEBUG}; const masterName: string{$ENDIF}): bool;
begin
{$IFDEF UNA_GATE_PROFILE}
  profileMarkEnter(f_profileIndex);
{$ENDIF}
  result := f_event.waitFor(timeout);
{$IFDEF UNA_GATE_PROFILE}
  profileMarkLeave(f_profileIndex);
{$ENDIF}
  //
  if (result) then begin
    //
    inherited gateEnter(timeout, {$IFDEF DEBUG}masterName{$ENDIF});
    //
    f_masterThread := GetCurrentThread();
    f_inside := true;
    f_isBusy := true;
  end;
end;

// --  --
procedure unaOutProcessGate.gateLeave();
begin
  f_masterThread := 0;
  f_inside := false;
  f_event.setState();
  //
  inherited gateLeave();
end;


{ unaInProcessGate }

{$IFDEF UNA_USE_CS }

type
  proc_tryEnterCriticalSection = function(var lpCriticalSection: TRTLCriticalSection): BOOL; stdcall;
  proc_InitializeCriticalSectionAndSpinCount = function(var lpCriticalSection: TRTLCriticalSection; dwSpinCount: DWORD): BOOL; stdcall;

var
  te_proc: proc_tryEnterCriticalSection;
  te_procTested: bool = false;
  is_proc: proc_InitializeCriticalSectionAndSpinCount;
  //
  k32: hModule;

{$ENDIF }

// --  --
procedure unaInProcessGate.AfterConstruction();
{$IFDEF UNA_U

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -