I too thought that you were supposed to use TestDestroy with Wait, but I've tried it out and it doesn't work.
After I invoke the Wait method from within the Main Thread, the secondary thread's calls to TestDestroy
still return false.
Here's how my code works. Firstly, here's the code for the secondary thread:
Code: Select all
class Class_For_Secondary_Joinable_Thread : public wxThread {
public:
Class_For_Secondary_Joinable_Thread() : wxThread(wxTHREAD_JOINABLE) {}
void *Entry()
{
while ( !this->TestDestroy() )
{
/* Keep looping */
}
this->Sleep(5000);
}
};
The idea here is that when the Main Thread invokes the Wait method on the secondary thread, the secondary thread will stall for 5 seconds before ending.
Here's the code in the Main Thread:
Code: Select all
void Race_GUIMain::OnButton1( wxCommandEvent& event )
{
this->Disable(); /* Freeze the GUI */
p_secondary_joinable_thread->Wait(); /* This function takes 5 seconds to return! */
this->Enable();
/* Unfreeze the GUI */
m_button2->Enable(false);
/* Disable a specific button */
}
This code simply does not work. The Wait method
never returns because the TestDestroy method continues to return false every time.
I have a workaround for this whereby I use a global variable along with a critical section, but I was hoping I could simply use the Delete method.
Here's how I currently achieve my goal. First I have a class as follows:
Code: Select all
class CriticalSectionLocker_WaitingIndicator {
protected:
static wxCriticalSection cs;
static bool is_waiting;
public:
CriticalSectionLocker_WaitingIndicator() { cs.Enter(); }
~CriticalSectionLocker_WaitingIndicator() { cs.Leave(); }
void Set_As_Waiting()
{
is_waiting = true;
}
bool Test_Is_Waiting_And_Reset()
{
if ( is_waiting )
{
is_waiting = false;
return true;
}
return false;
}
};
Then from within my Main Thread, before I invoke the Wait method on the secondary thread, I do this:
Code: Select all
CriticalSectionLocker_WaitingIndicator().SetAsWaiting();
p_secondary_thread->Wait();
And then within the secondary thread, instead of calling TestDestroy, I do:
Code: Select all
void *Entry()
{
while ( !CriticalSectionLocker_WaitingIndicator().Test_Is_Waiting_And_Reset() )
{
/* Keep looping */
}
this->Sleep(5000);
}
This method works but obviously it would be much neater just to use Delete and TestDestroy.
I have actually tried using a combination of Delete, Wait and TestDestroy, and it works fine on wxGTK. However I don't know if what I'm doing is "correct", and I find that the wxWidgets manual is too vague.