title: Memory leakage (due to worker thread) at application close
body: <p>Get leakage report (Tsrch_slave_thread, TSimpleEvent) after closing the app. I understand the app quits before the thread can free itself, but how to avoid? How to wait for the thread to finish?   </p>
  
  <p>Thank You.</p>
  
  <hr>
  
  <p><strong>Definition of the worker thread >></strong><br>
  - FreeOnTerminate is set to true<br>
  - OnTerminate : TMaster.slvsrch_termination();</p>
  
  <pre><code>Tsrch_slave_thread = class(TThread)
  private
    FSW: TStopWatch;
  protected
    procedure Execute; override;
  public
    SimpleEvent: TSimpleEvent;
    master: TMaster;
    master_HWND: HWND;   
    procedure DoTerminate; override;
    constructor Create; 
    destructor Destroy; override;
  end;
  
  procedure Tsrch_slave_thread.Execute;
  var
    text_orig: string;
    activesearch: integer;
  begin
    FSW.Start;
    while not terminated do begin
      activesearch := master.CMD_LISTCNT; 
      //stopper refresh
      synchronize(procedure begin         
          with self.master do
            Fmasternode.text := FmasterDat.MstrName + ' (' + floattostr(Fsw.ElapsedMilliseconds / 1000) + 'sec - Searching)';
      end);
      if (SimpleEvent.WaitFor(2000) &lt;&gt; wrTimeOut) or (activesearch &lt;&gt; 1) then break;  
    end;
    FSW.Stop;  
  end;
  </code></pre>
  
  <p><strong>TMaster (holding the reference for the worker thread) >></strong></p>
  
  <pre><code>TMaster = class(TObject)
  private
     ...
     Fslave_search_thread : Tsrch_slave_thread;
     ...
  public
     ...
  end;
  </code></pre>
  
  <p><strong>Destructor of TMaster (i set the worker thread's terminate flag from here) >></strong></p>
  
  <pre><code>destructor TMaster.Destroy;
  begin
    FSlaveList.free; 
    DeallocateHWnd( fMsgHandlerHWND );
    if assigned( self.Fslave_search_thread ) then self.Fslave_search_thread.terminate; 
    inherited;      
  end;
  </code></pre>
  
  <p><strong>Freeing TMaster instances in the main form's OnClose event handler >></strong></p>
  
  <pre><code>procedure TfrmCLmain.FormClose(Sender: TObject; var Action: TCloseAction);
    ...
    node := frmDevTree.JvTreeView1.Items.GetFirstNode;
    if node.data &lt;&gt; nil then
    begin
      while Assigned(Node) do begin
        if TObject(node.data) is TMaster then
          TMaster(node.data).free;
        node := node.getNextSibling;
      end;
    end;
    ...
    freeandnil(udpsend);
    action := caFree;
  end;
  </code></pre>
  
  <p><strong>Destructor of Tsrch_slave_thread >></strong></p>
  
  <pre><code>destructor Tsrch_slave_thread.destroy;
  begin
    self.SimpleEvent.free;
    inherited;
  end;
  </code></pre>
  
  <p><strong>Tsrch_slave_thread.DoTerminate >></strong></p>
  
  <pre><code>procedure Tsrch_slave_thread.DoTerminate;
  begin
    inherited;
    self.master.FlastSearchTime := self.FSW.ElapsedMilliseconds / 1000;
    self.simpleEvent.SetEvent; 
  end;
  </code></pre>
  
  <p><strong>Tsrch_slave_thread's OnTerminate event handler >></strong></p>
  
  <pre><code>procedure TMaster.slvsrch_termination(Sender: TObject);
  begin
    if Assigned(Fslave_search_thread) then
    begin
      self.FLastSearchTime := Fslave_search_thread.FSW.ElapsedMilliseconds - SEARCH_DELAY_SEC;  
      Fslave_search_thread := nil;
    end;
    ... 
    postmessage ( self.FMasterDevFrmHND, WM_SLVSRCH_COMPLETE, integer(self), 0);  
  end;
  </code></pre>