diff --git a/OtlCollections.pas b/OtlCollections.pas index c0aba06f..44f6db7e 100644 --- a/OtlCollections.pas +++ b/OtlCollections.pas @@ -362,6 +362,53 @@ destructor TOmniBlockingCollection.Destroy; inherited Destroy; end; { TOmniBlockingCollection.Destroy } +function TOmniBlockingCollection.TryAdd(const value: TOmniValue): boolean; +var + {$IFDEF MSWINDOWS} + awaited: cardinal; + {$ELSE} + waitResult: TWaitResult; + Signaller: IOmniSynchro; + {$ENDIF} +begin + obcAddCountAndCompleted.Increment; + try + // IsCompleted can not change during the execution of this function + Result := not IsCompleted; + if Result then begin + obcAccessed := true; + if obcThrottling and (obcApproxCount.Value >= obcHighWaterMark) then begin + {$IFDEF MSWINDOWS} + {$WARN SYMBOL_PLATFORM OFF} + Win32Check(ResetEvent(obcNotOverflow)); + {$WARN SYMBOL_PLATFORM ON} + {$ELSE} + obcNotOverflow.Reset; + {$ENDIF ~MSWINDOWS} + // it's possible that messages were removed and obcNotOverflow set *before* the + // previous line has executed so test again ... + if obcThrottling and (obcApproxCount.Value >= obcHighWaterMark) then begin + obcAddCountAndCompleted.Decrement; // Leave the Add temporarily so that CompleteAdding can succeed + {$IFDEF MSWINDOWS} + awaited := DSiWaitForTwoObjects(obcCompletedSignal, obcNotOverflow, false, INFINITE); + obcAddCountAndCompleted.Increment; // Re-enter Add; queue may be now in 'completed' state + if (awaited = WAIT_OBJECT_0) or IsCompleted then begin + {$ELSE} + waitResult := FCompletedWaiter.WaitAny(INFINITE,Signaller); + obcAddCountAndCompleted.Increment; + if ((waitResult = wrSignaled) and (Signaller = obcCompletedSignal)) or IsCompleted then begin + {$ENDIF} + Result := false; // completed + Exit; + end; + end; + end; + obcCollection.Enqueue(value); + obcApproxCount.Increment; + end; + finally obcAddCountAndCompleted.Decrement; end; +end; { TOmniBlockingCollection.TryAdd } + procedure TOmniBlockingCollection.Add(const value: TOmniValue); begin if not TryAdd(value) then @@ -421,6 +468,11 @@ function TOmniBlockingCollection.IsFinalized: boolean; Result := IsCompleted and obcCollection.IsEmpty; end; { TOmniBlockingCollection.IsFinalized } +function TOmniBlockingCollection.Take(var value: TOmniValue): boolean; +begin + Result := TryTake(value, INFINITE); +end; { TOmniBlockingCollection.Take } + function TOmniBlockingCollection.Next: TOmniValue; begin if not Take(Result) then @@ -444,11 +496,6 @@ procedure TOmniBlockingCollection.SetThrottling(highWaterMark, lowWaterMark: int obcThrottling := true; end; { TOmniBlockingCollection.SetThrottling } -function TOmniBlockingCollection.Take(var value: TOmniValue): boolean; -begin - Result := TryTake(value, INFINITE); -end; { TOmniBlockingCollection.Take } - {$IFDEF OTL_Generics} {$IFDEF OTL_HasArrayOfT} {$IFDEF OTL_ERTTI} @@ -616,53 +663,6 @@ class function TOmniBlockingCollection.ToArray(const coll: IOmniBlockingColle {$ENDIF OTL_HasArrayOfT} {$ENDIF OTL_Generics} -function TOmniBlockingCollection.TryAdd(const value: TOmniValue): boolean; -var - {$IFDEF MSWINDOWS} - awaited: cardinal; - {$ELSE} - waitResult: TWaitResult; - Signaller: IOmniSynchro; - {$ENDIF} -begin - obcAddCountAndCompleted.Increment; - try - // IsCompleted can not change during the execution of this function - Result := not IsCompleted; - if Result then begin - obcAccessed := true; - if obcThrottling and (obcApproxCount.Value >= obcHighWaterMark) then begin - {$IFDEF MSWINDOWS} - {$WARN SYMBOL_PLATFORM OFF} - Win32Check(ResetEvent(obcNotOverflow)); - {$WARN SYMBOL_PLATFORM ON} - {$ELSE} - obcNotOverflow.Reset; - {$ENDIF ~MSWINDOWS} - // it's possible that messages were removed and obcNotOverflow set *before* the - // previous line has executed so test again ... - if obcThrottling and (obcApproxCount.Value >= obcHighWaterMark) then begin - obcAddCountAndCompleted.Decrement; // Leave the Add temporarily so that CompleteAdding can succeed - {$IFDEF MSWINDOWS} - awaited := DSiWaitForTwoObjects(obcCompletedSignal, obcNotOverflow, false, INFINITE); - obcAddCountAndCompleted.Increment; // Re-enter Add; queue may be now in 'completed' state - if (awaited = WAIT_OBJECT_0) or IsCompleted then begin - {$ELSE} - waitResult := FCompletedWaiter.WaitAny(INFINITE,Signaller); - obcAddCountAndCompleted.Increment; - if ((waitResult = wrSignaled) and (Signaller = obcCompletedSignal)) or IsCompleted then begin - {$ENDIF} - Result := false; // completed - Exit; - end; - end; - end; - obcCollection.Enqueue(value); - obcApproxCount.Increment; - end; - finally obcAddCountAndCompleted.Decrement; end; -end; { TOmniBlockingCollection.TryAdd } - {$IFDEF MSWINDOWS} function TOmniBlockingCollection.TryTake(var value: TOmniValue; timeout_ms: cardinal): boolean; diff --git a/OtlSync.pas b/OtlSync.pas index 5c57382e..3577e804 100644 --- a/OtlSync.pas +++ b/OtlSync.pas @@ -1778,6 +1778,14 @@ function TLightweightMREWEx.TryBeginWrite(timeout: cardinal): boolean; { Locked } +procedure Locked.Clear; +begin + FLifecycle := nil; + FInitialized := false; + FValue := Default(T); + FOwnsObject := false; +end; { Locked } + constructor Locked.Create(const value: T; ownsObject: boolean); begin {$IFDEF OTL_HasLightweightMREW} @@ -1850,14 +1858,6 @@ function Locked.BeginWrite: T; end; { Locked.BeginWrite } {$ENDIF OTL_HasLightweightMREW} -procedure Locked.Clear; -begin - FLifecycle := nil; - FInitialized := false; - FValue := Default(T); - FOwnsObject := false; -end; { Locked } - {$IFDEF OTL_HasLightweightMREW} procedure Locked.EndRead; begin @@ -1882,6 +1882,23 @@ function Locked.Enter: T; Result := FValue; end; { Locked.Enter } +procedure Locked.Leave; +begin + {$IFDEF OTL_HasLightweightMREW} + FLock.EndWrite; + {$ELSE ~OTL_HasLightweightMREW} + FLock.Release; + {$ENDIF ~OTL_HasLightweightMREW} + {$IFDEF DEBUG} + FLockCount.Decrement; + {$ENDIF DEBUG} +end; { Locked.Leave } + +procedure Locked.Release; +begin + Leave; +end; { Locked.Release } + procedure Locked.Free; begin if FInitialized then begin @@ -1971,18 +1988,6 @@ function Locked.Initialize: T; end; { Locked.Initialize } {$ENDIF OTL_ERTTI} -procedure Locked.Leave; -begin - {$IFDEF OTL_HasLightweightMREW} - FLock.EndWrite; - {$ELSE ~OTL_HasLightweightMREW} - FLock.Release; - {$ENDIF ~OTL_HasLightweightMREW} - {$IFDEF DEBUG} - FLockCount.Decrement; - {$ENDIF DEBUG} -end; { Locked.Leave } - procedure Locked.Locked(proc: TProc); begin Acquire; @@ -1999,11 +2004,6 @@ procedure Locked.Locked(proc: TProcT); finally Release; end; end; { Locked.Locked } -procedure Locked.Release; -begin - Leave; -end; { Locked.Release } - {$IFDEF OTL_HasLightweightMREW} function Locked.TryBeginRead: boolean; begin diff --git a/src/DSiWin32.pas b/src/DSiWin32.pas index ab7d387e..edf9af5e 100644 --- a/src/DSiWin32.pas +++ b/src/DSiWin32.pas @@ -1636,7 +1636,7 @@ TDSiFileInfo = class const workDir: string = ''; wait: boolean = false; startInfo: PStartupInfo = nil): cardinal; overload; function DSiExecuteInSession(sessionID: DWORD; const commandLine: string; - var processInfo: TProcessInformation; workDir: string = ''): boolean; + var processInfo: TProcessInformation; const workDir: string = ''): boolean; function DSiGetProcessAffinity: string; function DSiGetProcessAffinityMask: DSiNativeUInt; function DSiGetProcessID(const processName: string; var processID: DWORD): boolean; @@ -5612,7 +5612,7 @@ ACCESS_ALLOWED_ACE = record specified or 0 in other cases. } function DSiExecuteInSession(sessionID: DWORD; const commandLine: string; - var processInfo: TProcessInformation; workDir: string): boolean; + var processInfo: TProcessInformation; const workDir: string): boolean; var cmdLine : string; hToken : THandle; diff --git a/src/DetailedRTTI.pas b/src/DetailedRTTI.pas index 2222ffff..e28477ef 100644 --- a/src/DetailedRTTI.pas +++ b/src/DetailedRTTI.pas @@ -41,7 +41,7 @@ TObjectHelper = class helper for TObject function RTTIMethodsAsString: string; end; - function DescriptionOfMethod( Obj: TObject; MethodName: string ): string; + function DescriptionOfMethod( Obj: TObject; const MethodName: string ): string; {$ENDIF HAS_RECORDHELPERS} implementation @@ -62,7 +62,7 @@ implementation {$IFDEF HAS_RECORDHELPERS} -function DescriptionOfMethod( Obj: TObject; MethodName: string ): string; +function DescriptionOfMethod( Obj: TObject; const MethodName: string ): string; var header: PMethodInfoHeader; headerEnd: Pointer; diff --git a/src/GpLists.pas b/src/GpLists.pas index bf01a78b..0780e9c0 100644 --- a/src/GpLists.pas +++ b/src/GpLists.pas @@ -8208,6 +8208,11 @@ procedure TGpSkipList.Clear; Initialize; end; { TGpSkipList } +function TGpSkipList.GetKey(const el: T): K; +begin + Result := FGetKey(el); +end; { TGpSkipList } + function TGpSkipList.Compare(const key: K; el: TGpSkipListEl): integer; begin Result := Compare(key, GetKey(el.Element)); @@ -8340,11 +8345,6 @@ function TGpSkipList.GetEnumerator: TGpSkipListEnumerator; Result := TGpSkipListEnumerator.Create(FHead, FTail); end; { TGpSkipList } -function TGpSkipList.GetKey(const el: T): K; -begin - Result := FGetKey(el); -end; { TGpSkipList } - procedure TGpSkipList.Initialize; var iPtr: integer; diff --git a/src/GpStuff.pas b/src/GpStuff.pas index 5c7c705a..6a178b45 100644 --- a/src/GpStuff.pas +++ b/src/GpStuff.pas @@ -724,7 +724,7 @@ function IFF(condit: boolean; iftrue, iffalse: TDateTime): TDateTime; overload; function IFF64(condit: boolean; iftrue, iffalse: int64): int64; {$IFDEF GpStuff_Inline}inline;{$ENDIF} {$IFDEF MSWINDOWS} {$IFDEF Unicode} -function IFF(condit: boolean; iftrue, iffalse: AnsiString): AnsiString; overload; {$IFDEF GpStuff_Inline}inline;{$ENDIF} +function IFF(condit: boolean; const iftrue, iffalse: AnsiString): AnsiString; overload; {$IFDEF GpStuff_Inline}inline;{$ENDIF} {$ENDIF Unicode} {$ENDIF MSWINDOWS} @@ -953,7 +953,7 @@ function IndexOfListA(const value: AnsiString; const values: array of AnsiString {$IFDEF GpStuff_TArrayOfT} function LinearMap(value: real; const x, y: TArray): real; -function SplitList(const aList: string; delim: string; const quoteChar: string = ''; +function SplitList(const aList: string; const delim: string; const quoteChar: string = ''; stripQuotes: boolean = true): TArray; overload; function SplitList(const aList: string; delim: TSysCharSet; const quoteChar: string = ''; stripQuotes: boolean = true): TArray; overload; @@ -1204,7 +1204,7 @@ function AutoExecute(proc: TProc): IGpAutoExecute; {$ENDIF GpStuff_Anonymous} //copied from GpString unit -procedure GetDelimiters(const list: string; delim: string; const quoteChar: string; +procedure GetDelimiters(const list: string; const delim: string; const quoteChar: string; addTerminators: boolean; var delimiters: TDelimiters); overload; var chk : boolean; @@ -1409,7 +1409,7 @@ function IFF64(condit: boolean; iftrue, iffalse: int64): int64; {$IFDEF MSWINDOWS} {$IFDEF Unicode} -function IFF(condit: boolean; iftrue, iffalse: AnsiString): AnsiString; +function IFF(condit: boolean; const iftrue, iffalse: AnsiString): AnsiString; begin if condit then Result := iftrue @@ -1510,6 +1510,26 @@ function OpenArrayToVarArray(aValues: array of const): Variant; end; //for i end; { OpenArrayToVarArray } +procedure OutputDebugString(const msg: string); +begin +{$IFDEF MSWINDOWS} +{$WARN SYMBOL_PLATFORM OFF} + if DebugHook <> 0 then + Windows.OutputDebugString(PChar(msg)); +{$WARN SYMBOL_PLATFORM ON} +{$ENDIF} +end; { OutputDebugString } + +procedure OutputDebugString(const msg: string; const params: array of const); +begin +{$IFDEF MSWINDOWS} +{$WARN SYMBOL_PLATFORM OFF} + if DebugHook <> 0 then + OutputDebugString(Format(msg, params)); +{$WARN SYMBOL_PLATFORM ON} +{$ENDIF} +end; { OutputDebugString } + function FormatDataSize(value: int64): string; begin if value < 1024*1024 then @@ -2275,7 +2295,7 @@ function LinearMap(value: real; const x, y: TArray): real; raise Exception.Create('LinearMap: Internal error. This line should never be executed.'); end; { LinearMap } -function SplitList(const aList: string; delim: string; const quoteChar: string = ''; +function SplitList(const aList: string; const delim: string; const quoteChar: string = ''; stripQuotes: boolean = true): TArray; var delimiters: TDelimiters; @@ -2698,26 +2718,6 @@ function GetRefCount(const intf: IInterface): integer; intf._Release; end; { GetRefCount } -procedure OutputDebugString(const msg: string); -begin -{$IFDEF MSWINDOWS} -{$WARN SYMBOL_PLATFORM OFF} - if DebugHook <> 0 then - Windows.OutputDebugString(PChar(msg)); -{$WARN SYMBOL_PLATFORM ON} -{$ENDIF} -end; { OutputDebugString } - -procedure OutputDebugString(const msg: string; const params: array of const); -begin -{$IFDEF MSWINDOWS} -{$WARN SYMBOL_PLATFORM OFF} - if DebugHook <> 0 then - OutputDebugString(Format(msg, params)); -{$WARN SYMBOL_PLATFORM ON} -{$ENDIF} -end; { OutputDebugString } - {$IFDEF GpStuff_TThread_Current} procedure SetDataBreakpoint(idx: TDataBreakpointIndex; address: pointer; condition: TDataBreakpointCondition; dataSize: TDataBreakpointDataSize); @@ -3083,6 +3083,70 @@ function TGpMemoryStream.Write(const buffer; count: longint): longint; { TGpBuffer } +procedure TGpBuffer.Add(b: byte); +begin + FData.Seek(0, soEnd); + FData.Write(b, 1); +end; { TGpBuffer.Add } + +{$IFDEF MSWINDOWS} +procedure TGpBuffer.Add(ch: AnsiChar); +begin + Add(byte(ch)); +end; { TGpBuffer.Add } +{$ENDIF} + +procedure TGpBuffer.Allocate(size: integer); +begin + Assert(size >= 0); + FData.Size := size; +end; { TGpBuffer.Allocate } + +procedure TGpBuffer.Append(data: pointer; size: integer); +begin + if size > 0 then begin + FData.Seek(0, soEnd); + FData.Write(data^, size); + end; +end; { TGpBuffer.Append } + +procedure TGpBuffer.Append(stream: TStream); +begin + if stream.Size > 0 then begin + FData.Seek(0, soEnd); + AsStream.CopyFrom(stream, 0); + end; +end; { TGpBuffer.Append } + +procedure TGpBuffer.Append(const buffer: IGpBuffer); +begin + Append(buffer.Value, buffer.Size); +end; { TGpBuffer.Append } + +procedure TGpBuffer.Assign(data: pointer; size: integer); +begin + Allocate(size); + if size > 0 then + Move(data^, Value^, size); +end; { TGpBuffer.Assign } + +procedure TGpBuffer.Assign(stream: TStream); +begin + Size := 0; + Append(stream); +end; { TGpBuffer.Assign } + +procedure TGpBuffer.Assign(const buffer: IGpBuffer); +begin + Size := 0; + Append(buffer); +end; { TGpBuffer.Assign } + +procedure TGpBuffer.Clear; +begin + Allocate(0); +end; { TGpBuffer.Clear } + constructor TGpBuffer.Create; begin inherited Create; @@ -3187,70 +3251,6 @@ class function TGpBuffer.Make: IGpBuffer; Result := TGpBuffer.Create; end; { TGpBuffer.Make } -procedure TGpBuffer.Add(b: byte); -begin - FData.Seek(0, soEnd); - FData.Write(b, 1); -end; { TGpBuffer.Add } - -{$IFDEF MSWINDOWS} -procedure TGpBuffer.Add(ch: AnsiChar); -begin - Add(byte(ch)); -end; { TGpBuffer.Add } -{$ENDIF} - -procedure TGpBuffer.Allocate(size: integer); -begin - Assert(size >= 0); - FData.Size := size; -end; { TGpBuffer.Allocate } - -procedure TGpBuffer.Append(data: pointer; size: integer); -begin - if size > 0 then begin - FData.Seek(0, soEnd); - FData.Write(data^, size); - end; -end; { TGpBuffer.Append } - -procedure TGpBuffer.Append(stream: TStream); -begin - if stream.Size > 0 then begin - FData.Seek(0, soEnd); - AsStream.CopyFrom(stream, 0); - end; -end; { TGpBuffer.Append } - -procedure TGpBuffer.Append(const buffer: IGpBuffer); -begin - Append(buffer.Value, buffer.Size); -end; { TGpBuffer.Append } - -procedure TGpBuffer.Assign(data: pointer; size: integer); -begin - Allocate(size); - if size > 0 then - Move(data^, Value^, size); -end; { TGpBuffer.Assign } - -procedure TGpBuffer.Assign(stream: TStream); -begin - Size := 0; - Append(stream); -end; { TGpBuffer.Assign } - -procedure TGpBuffer.Assign(const buffer: IGpBuffer); -begin - Size := 0; - Append(buffer); -end; { TGpBuffer.Assign } - -procedure TGpBuffer.Clear; -begin - Allocate(0); -end; { TGpBuffer.Clear } - function TGpBuffer.Equals(const buffer: IGpBuffer): boolean; begin Result := false;