ReferenceInterface(opInsert) is broken
Original Reporter info from Mantis: Craig Peterson @boramis
-
Reporter name: Craig Peterson
Original Reporter info from Mantis: Craig Peterson @boramis
- Reporter name: Craig Peterson
Description:
ReferenceInterface is supposed to add and remove the interface's implementing component from the FFreeNotifies list, but instead, when called with opInsert, it just immediately calls Notification. Since it isn't actually added to the FreeNotifies list, the calling component never receives notification when the implementing component is freed.
The program listed in "Steps to Reproduce" prints "Pass" under Delphi and "Fail" under FreePascal. The correct implementation is given in Additional Information.
Steps to reproduce:
program project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
{$R *.res}
var
Notified: Boolean;
type
TMyComponent = class(TComponent)
procedure Notification(AComponent: TComponent;
Operation: TOperation); override;
end;
procedure TMyComponent.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited;
Notified := True;
end;
var
Comp1, Comp2: TComponent;
Intf: IUnknown;
begin
Comp1 := TMyComponent.Create(nil);
Comp2 := TMyComponent.Create(nil);
Intf := Comp2;
Comp1.ReferenceInterface(Intf, opInsert);
Notified := False;
Comp2.Free;
if Notified then
WriteLn('Pass')
else
WriteLn('Fail')
end.
Additional information:
procedure TComponent.ReferenceInterface(const intf:IInterface;op:TOperation);
var ref : IInterfaceComponentReference;
comp : TComponent;
begin
if assigned(intf) and supports(intf,IInterfaceComponentReference,ref) then
begin
comp:=ref.getcomponent;
if op = opInsert then
comp.FreeNotification(Self)
else
comp.RemoveFreeNotification(Self);
end;
end;
Mantis conversion info:
- Mantis ID: 20808
- Version: 2.7.1
- Fixed in version: 3.0.0
- Fixed in revision: 20616 (#05999225)