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 ae63eaa1..053df896 100644 --- a/OtlSync.pas +++ b/OtlSync.pas @@ -1567,6 +1567,14 @@ class function Atomic.Initialize(var storage: I): I; { 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 Clear; @@ -1592,13 +1600,10 @@ procedure Locked.Acquire; FLock.Acquire; end; { Locked.Acquire } -procedure Locked.Clear; +procedure Locked.Release; begin - FLifecycle := nil; - FInitialized := false; - FValue := Default(T); - FOwnsObject := false; -end; { Locked } + FLock.Release; +end; { Locked.Release } procedure Locked.Free; begin @@ -1697,11 +1702,6 @@ procedure Locked.Locked(proc: TProcT); finally Release; end; end; { Locked.Locked } -procedure Locked.Release; -begin - FLock.Release; -end; { Locked.Release } - {$IFDEF MSWINDOWS} { TOmniLockManager.TNotifyPair } diff --git a/src/GpLists.pas b/src/GpLists.pas index 8d538654..7c61813e 100644 --- a/src/GpLists.pas +++ b/src/GpLists.pas @@ -7832,6 +7832,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)); @@ -7964,11 +7969,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 f0a1b8ca..eeec11bc 100644 --- a/src/GpStuff.pas +++ b/src/GpStuff.pas @@ -995,6 +995,26 @@ implementation NativeUInt = cardinal; {$ENDIF} +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_ValuesEnumerators} type TGpIntegerValueEnumerator = class(TInterfacedObject, IGpIntegerValueEnumerator) @@ -1139,7 +1159,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; @@ -1185,7 +1205,7 @@ procedure GetDelimiters(const list: string; delim: string; const quoteChar: stri SetLength(delimiters,idx); end; { GetDelimiters } -procedure GetDelimiters(const list: string; delim: TSysCharSet; const quoteChar: string; +procedure GetDelimiters(const list: string; const delim: TSysCharSet; const quoteChar: string; addTerminators: boolean; var delimiters: TDelimiters); overload; var chk : boolean; @@ -2479,26 +2499,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 } - function ClassNameEx(obj: TObject): string; begin if assigned(obj) then @@ -2807,6 +2807,44 @@ function TGpMemoryStream.Write(const buffer; count: longint): longint; { TGpBuffer } +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.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; @@ -2924,20 +2962,6 @@ procedure TGpBuffer.Add(ch: AnsiChar); 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 @@ -2951,30 +2975,6 @@ procedure TGpBuffer.Append(const buffer: IGpBuffer); 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 } - {$IFDEF MSWINDOWS} function TGpBuffer.GetAsAnsiString: AnsiString; var