Re: [fpc-devel] FreeNotification and opRemove
On Sun, 11 Mar 2012, Martin wrote: On 08/03/2012 13:34, Martin wrote: On 08/03/2012 13:08, michael.vancann...@wisa.be wrote: On Thu, 8 Mar 2012, Martin wrote: Further more: the program below, does not crash in delphi (turbo delphi) I also noticed. I suspect the problem is the owner; If it gets a free notification, it should pass it to all the children. I initially posted this to see if the behaviour would be considered a bug (rather than wrong user code) Seeing that Delphi does not crash, I assume I can consider it a bug, and report? Yes, please. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeNotification and opRemove
On 08/03/2012 13:34, Martin wrote: On 08/03/2012 13:08, michael.vancann...@wisa.be wrote: On Thu, 8 Mar 2012, Martin wrote: Further more: the program below, does not crash in delphi (turbo delphi) I also noticed. I suspect the problem is the owner; If it gets a free notification, it should pass it to all the children. I initially posted this to see if the behaviour would be considered a bug (rather than wrong user code) Seeing that Delphi does not crash, I assume I can consider it a bug, and report? I don't think that is it. In the example below C1 is no longer owned, when C2 is destroyed, so the problem would persist. The problem is that opRemove breaks the bi-directional bounding of FreeNotifications. When C2 gets the opREmove, it must mot just remove it's own entry, but also remove the entry C1 has ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeNotification and opRemove
Martin schrieb: When C2 gets the opREmove, it must mot just remove it's own entry, but also remove the entry C1 has The meaning of opRemove is unclear. IMO it doesn't make sense in the example code, because the owner of a component can change many times, without meaning that the component is being destroyed. In such a scenario the receiver can not know whether (when) the notification should be removed, the notification itself is quite useless. Owner.RemoveComponent(C1); // C2 Gets on opRemove DoDi ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] FreeNotification and opRemove
I found a behaviour, of which I am not sure, if it is intended. Maybe someone can comment My understanding is that FreeNotification are *always* set up bi-directional ? At least C1.FreeNotification(C2); will set up for C1 to inform C2, and for C2 to inform C1 whichever is destroyed first to call the other And C1.RemoveFreeNotification(C2); will remove both. C2.Notification(C1, opRemove); breaks that. It will lead to C2 removing C1 from it's list of FreeNotifies, but C1 will keep C2 on the list. If then C2 is destroyed, it does not inform C1 about that, and C1 ends up with a dangling pointer to the no longer existing C2. Destroying C2 will then crash. In the example below (compile with -gt) opRemove is caused by Owner.RemoveComponent. It crashes on the last line. I was briefly wondering, if in case C1 did call C1.FreeNotification(c2);, then C1 should overwrite Notification and check for the opRemove and call RemoveFreeNotification itself? But if that was the case, then why does TComponent interfer with the FreeNotify list at all? program Project1; {$mode objfpc}{$H+} uses Classes; var Owner, C1, C2: TComponent; begin Owner := TComponent.Create(nil); C1 := TComponent.Create(Owner); C2 := TComponent.Create(Owner); C1.FreeNotification(c2); Owner.RemoveComponent(C1); // C2 Gets on opRemove C2.Free; C1.Free; // crash ReadLn; end. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeNotification and opRemove
Further more: the program below, does not crash in delphi (turbo delphi) On 08/03/2012 09:56, Martin wrote: I found a behaviour, of which I am not sure, if it is intended. Maybe someone can comment My understanding is that FreeNotification are *always* set up bi-directional ? At least C1.FreeNotification(C2); will set up for C1 to inform C2, and for C2 to inform C1 whichever is destroyed first to call the other And C1.RemoveFreeNotification(C2); will remove both. C2.Notification(C1, opRemove); breaks that. It will lead to C2 removing C1 from it's list of FreeNotifies, but C1 will keep C2 on the list. If then C2 is destroyed, it does not inform C1 about that, and C1 ends up with a dangling pointer to the no longer existing C2. Destroying C2 will then crash. In the example below (compile with -gt) opRemove is caused by Owner.RemoveComponent. It crashes on the last line. I was briefly wondering, if in case C1 did call C1.FreeNotification(c2);, then C1 should overwrite Notification and check for the opRemove and call RemoveFreeNotification itself? But if that was the case, then why does TComponent interfer with the FreeNotify list at all? program Project1; {$mode objfpc}{$H+} uses Classes; var Owner, C1, C2: TComponent; begin Owner := TComponent.Create(nil); C1 := TComponent.Create(Owner); C2 := TComponent.Create(Owner); C1.FreeNotification(c2); Owner.RemoveComponent(C1); // C2 Gets on opRemove C2.Free; C1.Free; // crash ReadLn; end. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeNotification and opRemove
On Thu, 8 Mar 2012, Martin wrote: Further more: the program below, does not crash in delphi (turbo delphi) I also noticed. I suspect the problem is the owner; If it gets a free notification, it should pass it to all the children. Michael. On 08/03/2012 09:56, Martin wrote: I found a behaviour, of which I am not sure, if it is intended. Maybe someone can comment My understanding is that FreeNotification are *always* set up bi-directional ? At least C1.FreeNotification(C2); will set up for C1 to inform C2, and for C2 to inform C1 whichever is destroyed first to call the other And C1.RemoveFreeNotification(C2); will remove both. C2.Notification(C1, opRemove); breaks that. It will lead to C2 removing C1 from it's list of FreeNotifies, but C1 will keep C2 on the list. If then C2 is destroyed, it does not inform C1 about that, and C1 ends up with a dangling pointer to the no longer existing C2. Destroying C2 will then crash. In the example below (compile with -gt) opRemove is caused by Owner.RemoveComponent. It crashes on the last line. I was briefly wondering, if in case C1 did call C1.FreeNotification(c2);, then C1 should overwrite Notification and check for the opRemove and call RemoveFreeNotification itself? But if that was the case, then why does TComponent interfer with the FreeNotify list at all? program Project1; {$mode objfpc}{$H+} uses Classes; var Owner, C1, C2: TComponent; begin Owner := TComponent.Create(nil); C1 := TComponent.Create(Owner); C2 := TComponent.Create(Owner); C1.FreeNotification(c2); Owner.RemoveComponent(C1); // C2 Gets on opRemove C2.Free; C1.Free; // crash ReadLn; end. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeNotification and opRemove
On 08/03/2012 13:08, michael.vancann...@wisa.be wrote: On Thu, 8 Mar 2012, Martin wrote: Further more: the program below, does not crash in delphi (turbo delphi) I also noticed. I suspect the problem is the owner; If it gets a free notification, it should pass it to all the children. I don't think that is it. In the example below C1 is no longer owned, when C2 is destroyed, so the problem would persist. The problem is that opRemove breaks the bi-directional bounding of FreeNotifications. When C2 gets the opREmove, it must mot just remove it's own entry, but also remove the entry C1 has On 08/03/2012 09:56, Martin wrote: program Project1; {$mode objfpc}{$H+} uses Classes; var Owner, C1, C2: TComponent; begin Owner := TComponent.Create(nil); C1 := TComponent.Create(Owner); C2 := TComponent.Create(Owner); C1.FreeNotification(c2); Owner.RemoveComponent(C1); // C2 Gets on opRemove C2.Free; C1.Free; // crash ReadLn; end. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeNotification and opRemove
On 08/03/2012 13:34, Martin wrote: On 08/03/2012 13:08, michael.vancann...@wisa.be wrote: On Thu, 8 Mar 2012, Martin wrote: Further more: the program below, does not crash in delphi (turbo delphi) I also noticed. I suspect the problem is the owner; If it gets a free notification, it should pass it to all the children. I don't think that is it. In the example below C1 is no longer owned, when C2 is destroyed, so the problem would persist. The problem is that opRemove breaks the bi-directional bounding of FreeNotifications. When C2 gets the opREmove, it must mot just remove it's own entry, but also remove the entry C1 has In the following code, I thing is the problem: Procedure TComponent.Notification(AComponent: TComponent; Operation: TOperation); Var Runner : Longint; begin If (Operation=opRemove) and Assigned(FFreeNotifies) then begin FFreeNotifies.Remove(AComponent); ... It removes only one of the 2 notify entries. If opRemove is to remove FreeNotifications, then it mus remove them bi-directional, same as RemoveFreeNotification does On 08/03/2012 09:56, Martin wrote: program Project1; {$mode objfpc}{$H+} uses Classes; var Owner, C1, C2: TComponent; begin Owner := TComponent.Create(nil); C1 := TComponent.Create(Owner); C2 := TComponent.Create(Owner); C1.FreeNotification(c2); Owner.RemoveComponent(C1); // C2 Gets on opRemove C2.Free; C1.Free; // crash ReadLn; end. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeNotification and opRemove
On 08/03/2012 13:44, Martin wrote: In the following code, I thing is the problem: Procedure TComponent.Notification(AComponent: TComponent; Operation: TOperation); Var Runner : Longint; begin If (Operation=opRemove) and Assigned(FFreeNotifies) then begin FFreeNotifies.Remove(AComponent); ... It removes only one of the 2 notify entries. If opRemove is to remove FreeNotifications, then it mus remove them bi-directional, same as RemoveFreeNotification does That is: I have not checked if Delphi removes the FreeNotify at all. But I assume, if it does, it does both... ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] FreeNotification and opRemove
On 2012-03-08 14:51, Martin wrote: On 08/03/2012 13:44, Martin wrote: In the following code, I thing is the problem: Procedure TComponent.Notification(AComponent: TComponent; Operation: TOperation); Var Runner : Longint; begin If (Operation=opRemove) and Assigned(FFreeNotifies) then begin FFreeNotifies.Remove(AComponent); ... It removes only one of the 2 notify entries. If opRemove is to remove FreeNotifications, then it mus remove them bi-directional, same as RemoveFreeNotification does That is: I have not checked if Delphi removes the FreeNotify at all. But I assume, if it does, it does both... I can confirm the D7 does remove both - it calls: *AComponent.RemoveNotification(Self);* Regards, Torsten Bonde Christiansen. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel