title: Possible Deadlock on Calling FreeLibrary
body: <p>I have to write a DLL in Delphi XE7. I want to use TParallel.For in the DLL. The DLL is loaded into a C++ application, where everything works. However, when the application terminates, or a call to FreeLibrary is made, the application hangs. If I remove all the TParallel.For loops and replace them with standard loops, the application exits normally.</p>
  
  <p>The TParallel.For loops are very simple:</p>
  
  <pre><code>TParallel.For(0, inImage.Height -1, 
    Procedure(ty : integer)
    begin
      SomeProcedure(ty);
    end);
  </code></pre>
  
  <p>If I create a Delphi application with exactly the same code, everything works perfectly.</p>
  
  <p>After doing a lot of research and debugging, it looks like there is a deadlock which is preventing the C++ application from exiting when FreeLibrary is called, but I can't find where the problem is in TParallel.  </p>
  
  <p>Just to summarise the situation:</p>
  
  <ul>
  <li>The TParallel.For loops all complete and produce the correct results.</li>
  <li>The exact same TParallel.For code in a Delphi .exe works correctly.</li>
  <li>The DLL is loaded and the functions are called and perform correctly from within the C++ application.</li>
  <li>The C++ application will exit correctly if there are no TParallel.For loops.</li>
  <li>The C++ application will hang if there are TParallel.For loops.</li>
  <li>I am guessing that there is a deadlock which occurs when FreeLibrary is called.</li>
  <li>If I use the OTL threading library, everything works as it should.</li>
  </ul>
  
  <p>My questions are:</p>
  
  <p>Has anyone else experienced this behaviour?</p>
  
  <p>What is a good debugging strategy to find a deadlock in this situation?</p>
  
  <p>Any advice is greatly appreciated. </p>
  
  <p>UPDATE</p>
  
  <p>OK, so if you want Minimal, Complete and Verifiable example, here you go (thank you Stephen Ball):</p>
  
  <pre><code>library ADelphiDLL;
  
  uses
    System.SysUtils, System.Classes, Threading, SyncObjs;
  
  function IsPrime (N: Integer): Boolean;
  var
   Test: Integer;
  begin
   IsPrime := True;
   for Test := 2 to N - 1 do
     if (N mod Test) = 0 then
     begin
       IsPrime := False;
       break; {jump out of the for loop}
     end;
  end;
  
  function Prime(Max : integer) : boolean;
  var
    tot : integer;
  begin
     tot := 0;
     TParallel.For(1, Max, procedure (I: Integer)
      begin
        if IsPrime (I) then
          TInterlocked.Increment (Tot);
      end);
     return true;
     end;
  
  exports Prime;
  
  begin
     IsMultiThread := True;
  end.
  </code></pre>
  
  <p>in C++:</p>
  
  <pre><code>#include "stdafx.h"
  
  typedef bool(__stdcall *primesf)(int);
  
  void main()
  {
  HINSTANCE hGetDLL = LoadLibrary(L"ADelphiDLL.dll");
  primesf primes = (primesf)GetProcAddress(hGetProcIDDLL, "Primes");
  bool result = primes(100);
  FreeLibrary(hGetDLL);// &lt;-- Hangs here forever
  }
  </code></pre>
  
  <p>In response to the very "helpful" comments, "there is a defect in the code " and "debug it yourself", thank you, that is what I have been doing for a too long a time. So, if there is no help forthcoming here, I will try and get permission to switch to OTL, which does work in the DLL in question.</p>
  
  <p>UPDATE 2</p>
  
  <p>OTL works exactly as expected. So, yes, there is a "defect in the code". I give up. I will recommend abandoning Delphi altogether and then we can move everything over to C++ and C#. That has to be a much better short (and long term) solution.</p>