Git Product home page Git Product logo

Comments (4)

chinawsb avatar chinawsb commented on May 25, 2024

1.Declare a private variant:
private
FPendingSyncProcs:Integer;
2.Add reference counter change

procedure TBaseVirtualTree.ChangeTreeStatesAsync(EnterStates, LeaveStates: TVirtualTreeStates);
begin
  //TODO: If this works reliable, move to TWorkerThread
  if not (csDestroying in ComponentState) then
    begin
    //swish:Increment invoke refs
    AtomicIncrement(FPendingSyncProcs);
    TThread.Synchronize(nil, procedure
      begin
        //Decrement invoke refs
        AtomicDecrement(FPendingSyncProcs);
        // Prevent invalid combination tsUseCache + tsValidationNeeded (#915)
        if not ((tsUseCache in EnterStates) and (tsValidationNeeded in FStates + LeaveStates)) then
          DoStateChange(EnterStates, LeaveStates);
        if (tsValidating in FStates) and (tsValidating in LeaveStates) then
          UpdateEditBounds();
      end);
    end;
end;

procedure TBaseVirtualTree.MeasureItemHeight(const Canvas: TCanvas; Node: PVirtualNode);

// If the height of the given node has not yet been measured then do it now.

var
  NewNodeHeight: TDimension;

begin
  if not (vsHeightMeasured in Node.States) then
  begin
    Include(Node.States, vsHeightMeasured);
    if (toVariableNodeHeight in FOptions.MiscOptions) then
    begin
      NewNodeHeight := Node.NodeHeight;
      // Anonymous methods help to make this thread safe easily.
      if (MainThreadId <> GetCurrentThreadId) then
        begin
        //swish:Increment invoke refs
        AtomicIncrement(FPendingSyncProcs);
        TThread.Synchronize(nil,
          procedure
          begin
            //swish:Decrement invoke refs
            AtomicDecrement(FPendingSyncProcs);
            DoMeasureItem(Canvas, Node, NewNodeHeight);
            SetNodeHeight(Node, NewNodeHeight);
          end
        )
        end
      else
      begin
        DoMeasureItem(Canvas, Node, NewNodeHeight);
        SetNodeHeight(Node, NewNodeHeight);
      end;
    end;
  end;
end;

destructor TBaseVirtualTree.Destroy();
var
  WasValidating: Boolean;
begin
  WasValidating := (tsValidating in FStates) or (tsValidationNeeded in FStates); // Checking tsValidating is not enough, the TWorkerThread may be stuck in the first call to ChangeTreeStatesAsync()
  InterruptValidation(True);
  if WasValidating then
  begin
    // Make sure we dequeue the two synchronized calls from ChangeTreeStatesAsync(), fixes mem leak and AV reported in issue #1001, but is more a workaround.
    //swish:Add FPendingSyncProcs reference check avoid dead loop
    while CheckSynchronize() and (FPendingSyncProcs>0) do
      begin
      Sleep(1);
      end;
  end;// if
........

from virtual-treeview.

joachimmarder avatar joachimmarder commented on May 25, 2024

If checksynchronize always return true

Well, it shouldn't, unless synchronized methods were processed. If some code endlessly queues synchronized methods, then we would indeed run into a kind of endless loop in TBaseVirtualTree.Destroy(), but the root cause lies somewhere else, and that would be just a symptom.

from virtual-treeview.

chinawsb avatar chinawsb commented on May 25, 2024

Yes, it only occurs in a very few scenarios, but we should not assume that it will not happen. We should only care about which we queued. Once they are processed,loop shoud break. So my solution use a reference count for fix it.

from virtual-treeview.

chinawsb avatar chinawsb commented on May 25, 2024

For example, function A1 use TThread.ForceQueue invoke self for some reason(eg. wait some condition) .If use Application.ProcessMessages,it will block other queued methods,so we give up.

from virtual-treeview.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.