title: Are event handlers re-entrant in Embarcadero C++Builder?
body: <p>I'd like to ask some advice on how handle an Embarcadero CB10.1 issue with re-entrancy. Compiled in Debug configuration with "Disable all optimizations" set to true. I'm running on Win7.</p>
  
  <p>I have a simple test case. A form with two buttons. The OnClick event handler for each button calls the same CPU intensive function. Below is the header file followed by the program file.</p>
  
  <pre><code>#ifndef Unit1H
  #define Unit1H
  //---------------------------------------------------------------------------
  #include &lt;System.Classes.hpp&gt;
  #include &lt;Vcl.Controls.hpp&gt;
  #include &lt;Vcl.StdCtrls.hpp&gt;
  #include &lt;Vcl.Forms.hpp&gt;
  //---------------------------------------------------------------------------
  class TForm1 : public TForm
  {
  __published:    // IDE-managed Components
      TButton *Button1;
      TButton *Button2;
      void __fastcall Button1Click(TObject *Sender);
      void __fastcall Button2Click(TObject *Sender);
  private:    // User declarations
      double __fastcall CPUIntensive(double ButonNo);
      double __fastcall Spin(double Limit);
  
  public:     // User declarations
      __fastcall TForm1(TComponent* Owner);
  };
  //---------------------------------------------------------------------------
  extern PACKAGE TForm1 *Form1;
  //---------------------------------------------------------------------------
  #endif
  
  
  
  //---------------------------------------------------------------------------
  
  #include &lt;vcl.h&gt;
  #pragma hdrstop
  
  #include "Unit1.h"
  //---------------------------------------------------------------------------
  #pragma package(smart_init)
  #pragma resource "*.dfm"
  TForm1 *Form1;
  //---------------------------------------------------------------------------
  __fastcall TForm1::TForm1(TComponent* Owner)
      : TForm(Owner)
  {
  }
  
  //---------------------------------------------------------------------------
  
  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
  Button1-&gt;Caption = "Pushed";
  double retv = CPUIntensive(1);
  Button1-&gt;Caption = "Button1";
  if (retv) ShowMessage("Button1 Done");
  }
  //---------------------------------------------------------------------------
  
  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
  Button2-&gt;Caption = "Pushed";
  double retv = CPUIntensive(2);
  Button2-&gt;Caption = "Button2";
  if (retv) ShowMessage("Button2 Done");
  }
  //---------------------------------------------------------------------------
  
  double __fastcall TForm1::CPUIntensive(double ButtonNo)
  {
  //
  static bool InUse = false;
  if (InUse) {
      ShowMessage("Reentered by button number " + String(ButtonNo));
      while (InUse) {};
      }
  double retv;
  InUse = true;
  retv = Spin(30000);         // about 9 seconds on my computer
  //retv += Spin(30000);      // uncomment if you have a faster computer
  //retv += Spin(30000);
  InUse = false;
  return retv;
  }
  //---------------------------------------------------------------------------
  
  double __fastcall TForm1::Spin(double Limit)
  {
  double k;
  for (double i = 0 ; i &lt; Limit ; i++) {
      for (double j = 0 ; j &lt; Limit ; j++) {
          k = i + j;
          // here there can be calls to other VCL functions
          Application-&gt;ProcessMessages(); // added so UI would be responsive (2nd case)
          }
      }
  return k;
  }
  //---------------------------------------------------------------------------
  </code></pre>
  
  <p>-
  1st case : the code shown but WITHOUT the call to ProcessMessages().</p>
  
  <p>When I run this and click on button 1, CPU usage jumps up to almost
  100% for about 9 seconds. The form becomes unresponsive during this time.
  Can't move the form or click on button 2.</p>
  
  <p>That works as I would expect.</p>
  
  <p>2nd case : To make the form responsive to the user during the CPU
  intensive function, I added the ProcessMessages() call as shown.
  Now, I can move the form around and click on other buttons.</p>
  
  <p>That is not always good, because I could click on button 1 again or
  even click on button 2. Either click would fire off the CPU intensive function again. To prevent the CPU intensive function from running the second time, I made a static boolean flag "InUse". I set that
  when the function starts and clear it when the function completes.</p>
  
  <p>So I check the flag when I enter the CPU intensive function and
  if its set (it must have been set by a previous click on a button), I
  show a message and then wait for the flag to clear.</p>
  
  <p>But the flag never clears and my program loops on the 'while' statement
  forever. I would like the program to just wait for the CPU intensive function
  to complete and then just run it again.</p>
  
  <p>If I set a breakpoint in the Spin() function after I hit the deadlock,
  it never fires indicating that neither event is executing.</p>
  
  <p>I know the VCL is not thread safe but here, all of the processing takes
  place in the main thread. In my actual code, there are many calls to
  VCL functions so the CPU intensive function has to remain in the main
  thread.</p>
  
  <p>I considered Critical Sections and Mutexes but since everything is in
  the main thread, any use of them does no blocking.</p>
  
  <p>Maybe its a stack issue? Is there a solution that lets me handle this without the deadlock?</p>