Validity of Pointers to wxApp and wxFrame when Close() Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Blinkinhek
Experienced Solver
Experienced Solver
Posts: 91
Joined: Tue Aug 16, 2005 10:54 am

Validity of Pointers to wxApp and wxFrame when Close()

Post by Blinkinhek » Mon Jan 12, 2009 1:26 pm

I have an application which uses detached threads.
so wxApp creates wxFrame which creates wxThreads.
the wxThreads are running with the following simplified loop:

Code: Select all

void *cMainThread::Entry()
{
    while (!TestDestroy()) 
    {
        <various stuff>
        
    }
}
When the user selects 'Quit' via the frame menus, the 'OnQuit' event calls Close(). Am I correct that this will be 'detected' by the thread 'TestDestroy() method ?
Also, this means that any function calls or expression evaluations/manipulation of local and global variables in the inside of the While loop will carry on until the TestDestroy is called. Within this loop I do use calls that involve the wxFrame and wxApp (for example I post an event wxPostEvent(m_frame, event), and also use wxGetApp()) - therefore at what point do pointers to wxApp and wxFrame remain valid?
My program is causing a segmentation fault on exit, and I think it is due to the above situation, ie Close() does not wait for the wxThread to return, just signals to the thread that it should exit.

TIA

User avatar
doublemax
Moderator
Moderator
Posts: 15068
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax » Mon Jan 12, 2009 2:00 pm

When the user selects 'Quit' via the frame menus, the 'OnQuit' event calls Close(). Am I correct that this will be 'detected' by the thread 'TestDestroy() method ?
No, the thread knows nothing about this. Only explicit calling wxThread::Destroy() or implicit through its dtor will be recognized at TestDestroy().

Actually, gracefully terminating an application with detached threads still running is a non-trivial task ;)

Brute force method: call wxThread::Kill() in the OnClose handler (easy, but not recommended)

Clean method: In the OnClose handler, send wxThread::Destroy(), then wait till the thread has actually terminated.

Problem: As detached threads delete themselves, you don't even know if the call to wxThread::Destroy() is safe, as the thread object could be deleted already. To solve this problem, i keep a list of all running threads in my application object. When a thread is created i add it to the list, and in the thread's OnExit() call it removes itself from the list (all accesses to the list must of course be protected by a mutex). Then, in the OnClose handler, i send wxThread::Delete() to all running threads, then i wait till the list is empty.
Use the source, Luke!

Post Reply