mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-22 20:19:27 +02:00
LCL: Fix endless loop in ReleaseComponent (invoking itself via WM_NULL). Issue #40183
Change to only re-invoke ReleaseComponent if any component actually reached a ref-count of 0. If Components are re-added after a crash during destroying one of them, then they (may or may not) re-invoke immediately. But excluding the crashed one, so there is work to continue.
This commit is contained in:
parent
54d8f2bdb1
commit
0d415cb235
@ -1523,6 +1523,7 @@ type
|
|||||||
procedure DoIdleActions;
|
procedure DoIdleActions;
|
||||||
procedure MenuPopupHandler(Sender: TObject);
|
procedure MenuPopupHandler(Sender: TObject);
|
||||||
procedure ProcessAsyncCallQueue;
|
procedure ProcessAsyncCallQueue;
|
||||||
|
procedure DoDecLCLRefcountToZero(Sender: TObject);
|
||||||
procedure FreeComponent(Data: PtrInt);
|
procedure FreeComponent(Data: PtrInt);
|
||||||
procedure ReleaseComponents;
|
procedure ReleaseComponents;
|
||||||
procedure DoBeforeFinalization;
|
procedure DoBeforeFinalization;
|
||||||
|
@ -135,6 +135,7 @@ begin
|
|||||||
if Assigned(FOnDestroy) then FOnDestroy(Self);
|
if Assigned(FOnDestroy) then FOnDestroy(Self);
|
||||||
|
|
||||||
ProcessAsyncCallQueue;
|
ProcessAsyncCallQueue;
|
||||||
|
OnDecLCLRefcountToZero := nil;
|
||||||
|
|
||||||
if OnMenuPopupHandler=@MenuPopupHandler then
|
if OnMenuPopupHandler=@MenuPopupHandler then
|
||||||
OnMenuPopupHandler:=nil;
|
OnMenuPopupHandler:=nil;
|
||||||
@ -2331,6 +2332,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TApplication.DoDecLCLRefcountToZero(Sender: TObject);
|
||||||
|
begin
|
||||||
|
OnDecLCLRefcountToZero := nil;
|
||||||
|
QueueAsyncCall(@FreeComponent, 0);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TApplication.FreeComponent(Data: PtrInt);
|
procedure TApplication.FreeComponent(Data: PtrInt);
|
||||||
begin
|
begin
|
||||||
if Data<>0 then
|
if Data<>0 then
|
||||||
@ -2401,8 +2408,12 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
FComponentsToRelease.Add(AComponent);
|
FComponentsToRelease.Add(AComponent);
|
||||||
AComponent.FreeNotification(Self);
|
AComponent.FreeNotification(Self);
|
||||||
if IsFirstItem then
|
if IsFirstItem then begin
|
||||||
QueueAsyncCall(@FreeComponent, 0);
|
if TLCLComponent(AComponent).LCLRefCount>0 then
|
||||||
|
OnDecLCLRefcountToZero := @DoDecLCLRefcountToZero
|
||||||
|
else
|
||||||
|
QueueAsyncCall(@FreeComponent, 0);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -85,6 +85,9 @@ type
|
|||||||
property ReferenceAllocated: Boolean read GetReferenceAllocated;
|
property ReferenceAllocated: Boolean read GetReferenceAllocated;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
OnDecLCLRefcountToZero: TNotifyEvent;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -180,6 +183,8 @@ end;
|
|||||||
procedure TLCLComponent.DecLCLRefCount;
|
procedure TLCLComponent.DecLCLRefCount;
|
||||||
begin
|
begin
|
||||||
dec(FLCLRefCount);
|
dec(FLCLRefCount);
|
||||||
|
if (FLCLRefCount <= 0) and (OnDecLCLRefcountToZero <> nil) then
|
||||||
|
OnDecLCLRefcountToZero(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TLCLReferenceComponent }
|
{ TLCLReferenceComponent }
|
||||||
|
Loading…
Reference in New Issue
Block a user