Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


pyscripter last won the day on November 10 2019

pyscripter had the most liked content!

Community Reputation

88 Excellent


Technical Information

  • Delphi-Version
    Delphi 10.3 Rio

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. pyscripter

    Revisiting TThreadedQueue and TMonitor

    I have improved the fix to deal with TMonitor.Wait being called during unit finalization. Corner case but it did come up in a real application. See attached: MonitorWaitStackFix.pas
  2. pyscripter

    Embarcadero entries in the path

    Thank you all for your answers. What is wrong with removing all these entries. Does this cause Rad Studio to malfunction?
  3. That is so nice... Thanks for spotting the typo anyway. With the typo fixed the following test code: procedure Test(); begin try var Bob := TSmartPointer.Wrap(TTalking.Create('Bob')); Bob.Talk; var John := TSmartPointer.Wrap(TTalking.Create('John')); John.Talk; John := Bob; John.Talk; finally WriteLn('Do more stuff'); end; end; produces Bob is talking John is talking Release 0 John is gone Bob is talking Release 1 Release 0 Bob is gone Do more stuff with no AV or memory leak.
  4. True. Spring4D is the best! And for what it is (not) worth, I have voted for RSP-27375. Here is another one (more complex but still compact) which I think is comparable and similar in approach to Spring4D, based on a Stackoverflow question. I am adding it here for the completeness of the discussion. type TInjectType<T> = record public VMT: pointer; unknown: IInterface; RefCount: integer; AValue: T; end; TInject<T> = class public type TInjectType = TInjectType<T>; PInjectType = ^TInjectType; end; PInjectObjectType = TInject<TObject>.PInjectType; TSmartPointer = class class function Wrap<T: class>(const AValue: T): TFunc<T>; static; end; function Trick_Release(const obj: PInjectObjectType): Integer; stdcall; forward; function Trick_AddRef(const obj: PInjectObjectType): Integer; stdcall; forward; function Invoke(const obj: PInjectObjectType): TObject; forward; const PSEUDO_VMT: array [0 .. 3] of pointer = (nil, @Trick_AddRef, @Trick_Release, @Invoke); function Trick_AddRef(const obj: PInjectObjectType): Integer; stdcall; begin Result:= AtomicIncrement(Obj^.RefCount); end; function Trick_Release(const obj: PInjectObjectType): Integer; stdcall; begin Result:= AtomicDecrement(Obj^.RefCount); WriteLn('Release '+IntToStr(Obj.RefCount)); if Result = 0 then begin obj^.AValue.Free; FreeMem(obj); end; end; function Invoke(const obj: PInjectObjectType): TObject; begin Result:= obj^.AValue; end; class function TSmartPointer.Wrap<T>(const AValue: T): TFunc<T>; var p: PInjectObjectType; begin P:= GetMemory(SizeOf(TInjectType<T>)); p.RefCount:= 1; pointer(p.unknown):= p; p.VMT:= @PSEUDO_VMT; p.AValue:= AValue; pointer(Result):= pointer(TFunc<T>(p)); end; Note: typo corrected (see below).
  5. I remember @David Heffernan saying that the first thing he does when installing a new Delphi version is to remove the Embarcadero entries in the Windows path. Do I remember well? Are there any downsides to doing that?
  6. Minimalist implementation of SmartPointers based on a old post by Barry Kelly comparable to the Spring4D one in performance. type TObjectHandle<T: class> = class(TInterfacedObject, TFunc<T>) private FValue: T; public constructor Create(AValue: T); destructor Destroy; override; function Invoke: T; end; TSmartPointer = record class function Make<T: class>(AValue: T): TFunc<T>; static; end; constructor TObjectHandle<T>.Create(AValue: T); begin FValue := AValue; end; destructor TObjectHandle<T>.Destroy; begin FValue.Free; end; function TObjectHandle<T>.Invoke: T; begin Result := FValue; end; { TSmartPointer } class function TSmartPointer.Make<T>(AValue: T): TFunc<T>; begin Result := TObjectHandle<T>.Create(AValue); end; Used as in: var Bob := TSmartPointer.Make(TTalking.Create('Bob'))(); or var Bob := TSmartPointer.Make(TTalking.Create('Bob'));
  7. pyscripter

    You RAD Studio 10.4 Sydney appreciated features and bug fixes

    @Anders Melander The general rule that has always applied is that managed types (strings, interfaces, records with managed fields, dynamic arrays, etc,) are finalized at the end of the scope in which they are introduced. This included temp variables. The newly introduced managed records breaks this rule. Whether you like it better or not, it is inconsistent. And a local block does not solve the problem. The temp managed record will still self-destruct at the end of the statement it is used.
  8. pyscripter

    You RAD Studio 10.4 Sydney appreciated features and bug fixes

    Your example is not correct: Try: program Scope; {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes; type TTestScope = class(TInterfacedObject) destructor Destroy; override; end; { TTestScope } destructor TTestScope.Destroy; begin WriteLn('Gone'); inherited; end; procedure Test; var Foo: IUnknown; begin Foo := TTestScope.Create as IUnknown; WriteLn('Do stuff'); Foo := nil; // This does destroy the object WriteLn('Do more stuff'); end; begin Test(); ReadLn; end. Output: Do stuff Gone Do more stuff
  9. pyscripter

    You RAD Studio 10.4 Sydney appreciated features and bug fixes

    I think there is a serious issue with the timing of finalization of temp managed records which now is ASAP unlike regular records. Please see Timing of finalization of temporary managed records I would love to hear what the experts think about this. @Stefan Glienke @David Heffernan @Marco Cantu etc.
  10. pyscripter

    You RAD Studio 10.4 Sydney appreciated features and bug fixes

    Also the improvements in Vcl.Styles and DPI awareness are welcome. There are still a few outstanding issues: InputQuery scaling and styling issues Styled menus DPI scaling TCustomizeDlg not fully VCL styled
  11. pyscripter

    You RAD Studio 10.4 Sydney appreciated features and bug fixes

    Right now the quality portal is updated at a frenetic rate. There was a very large number of fixes, I think more than in any other previous version, and I was quite pleased that quite a few of my reports have been resolved, some of the unexpectedly: System.AnsiStrings AdjustLineBreaks not exported Memory leak in TInvokeableVariantType.DispInvoke Optimize TInvokeableVariantType.DispInvoke Wrongly premultiplied TWICImage when assigning a Bitmap with aDefined TButtonedEdit is not styled properly System.Threading got some attention with the famous Cancel and Wait issue resolved. Issues I would like to see fixed now and consider critical are: TThreadedQueue and TMonitor issue, possible solution InterlockedCompareExchange128 doesn't restore RBX Threading - Incorrect calculation of IdleWorkerThreadCount
  12. pyscripter

    MMX supports Delphi 10.4 Sydney

    That was quick!
  13. pyscripter

    Revisiting TThreadedQueue and TMonitor

    @Anders MelanderThanks for the explanation. I have updated my comment in the RSP.
  14. pyscripter

    Revisiting TThreadedQueue and TMonitor

    Are the MOV instructions after LOCK CMPXCHG16B [R10] needed? The following passes the stress test: {$IFDEF Win64} function InterlockedCompareExchange128(Destination: Pointer; ExchangeHigh, ExchangeLow: Int64; ComparandResult: Pointer): boolean; // The parameters are in the RCX, RDX, R8 and R9 registers per the MS x64 calling convention: // RCX Destination // RDX ExchangeHigh // R8 ExchangeLow // R9 ComparandResult // // CMPXCHG16B requires the following register setup: // RDX:RAX ComparandResult.High:ComparandResult.Low // RCX:RBX ExchangeHigh:ExchangeLow // See: https://www.felixcloutier.com/x86/cmpxchg8b:cmpxchg16b asm .PUSHNV RBX MOV R10,Destination // RCX MOV RBX,ExchangeLow // R8 MOV RCX,ExchangeHigh // RDX MOV RDX,[ComparandResult+8] // R9 MOV RAX,[ComparandResult] // R9 LOCK CMPXCHG16B [R10] // MOV [ComparandResult+8],RDX // R9 // MOV [ComparandResult],RAX // R9 SETZ AL end; {$ENDIF Win64}
  15. pyscripter

    Revisiting TThreadedQueue and TMonitor

    Correct, but in the fix it is declered as boolean. So I guess MOVZX EAX,AL is not needed. I am reattaching the amended file. MonitorWaitStackFix.pas