Thread deletion - where?

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
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 3362
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Thread deletion - where?

Post by ONEEYEMAN » Thu May 16, 2019 3:41 am

Hi,
When my application starts and the user press the button on the toolbar Im starting a thread.

But the deletion of the thread is performed like this:

Code: Select all

MainFrame::~MainFrame()
{
    delete m_db;
    m_db = NULL;
}

void MainFrame::OnClose(wxCloseEvent &event)
{
    {
        if( m_db )
            std::lock_guard<std::mutex>( m_db->GetTableVector().my_mutex );
        if( m_handler )
        {
#if defined _DEBUG
            printf( "Deleting the thread...\n\r" );
#endif
            if( m_handler->Delete() != wxTHREAD_NO_ERROR )
            {
            }
        }
    }
    while( 1 )
    {
#if defined _DEBUG
        printf( "Looping for thread deletionn\n\r" );
#endif
        {
        if( m_db )
            std::lock_guard<std::mutex>( m_db->GetTableVector().my_mutex );
        if( !m_handler )
                break;
        }
        wxThread::This()->Sleep( 1 );
    }
#if defined _DEBUG
    printf( "Thread destroyed. Deleting application....\n\r" );
#endif
    Destroy();
}
}
Now with this code I'm getting an exception on the MainFrane destructor.
Exception thrown at 0x761D5EF8 (KernelBase.dll) in docview.exe: 0x8001010E: The application called an interface that was marshalled for a different thread.
'docview.exe' (Win32): Unloaded 'C:\Windows\SysWOW64\msftedit.dll'
What is the proper way of destroying the thread and deleting the shared pointer?
Or maybe I should use std::shared_ptr<>( m_db )?

Thank you.

User avatar
evstevemd
Part Of The Furniture
Part Of The Furniture
Posts: 2240
Joined: Wed Jan 28, 2009 11:57 am
Location: United Republic of Tanzania
Contact:

Re: Thread deletion - where?

Post by evstevemd » Thu May 16, 2019 4:43 am

is m_db shared between threads
Chief Justice: We have trouble dear citizens!
Citizens: What it is his honor?
Chief Justice:Our president is an atheist, who will he swear to?
[Ubuntu 15.04/Windows 10 Pro - GCC/MinGW, CodeLite IDE et al]

Kvaz1r
Earned some good credits
Earned some good credits
Posts: 120
Joined: Tue Jun 07, 2016 1:07 pm

Re: Thread deletion - where?

Post by Kvaz1r » Thu May 16, 2019 7:12 am

Work with thread must be included into blocking section.
So this code apparently don't do what it should do:

Code: Select all

if( m_db )
            std::lock_guard<std::mutex>( m_db->GetTableVector().my_mutex );
Look for example in the documentation,
each call has own locker.

Code: Select all

void MyFrame::OnClose(wxCloseEvent&)
{
    {
        wxCriticalSectionLocker enter(m_pThreadCS);
        if (m_pThread)         // does the thread still exist?
        {
            wxMessageOutputDebug().Printf("MYFRAME: deleting thread");
            if (m_pThread->Delete() != wxTHREAD_NO_ERROR )
                wxLogError("Can't delete the thread!");
        }
    }       // exit from the critical section to give the thread
            // the possibility to enter its destructor
            // (which is guarded with m_pThreadCS critical section!)
    while (1)
    {
        { // was the ~MyThread() function executed?
            wxCriticalSectionLocker enter(m_pThreadCS);
            if (!m_pThread) break;
        }
        // wait for thread completion
        wxThread::This()->Sleep(1);
    }
    Destroy();
}

alys666
I live to help wx-kind
I live to help wx-kind
Posts: 186
Joined: Tue Oct 18, 2016 2:31 pm

Re: Thread deletion - where?

Post by alys666 » Thu May 16, 2019 9:45 am

if your thread is detached, to finish it you have to write( but you must be sure that it was not already exited, and autodeleted from heap.

Code: Select all

_thread->Delete(); //or somehow signal to him via shared variable, or queue that he must exit 
if thread is joinable:

Code: Select all

_thread->Delete(); //or somehow signal to him via shared variable, or queue that he must leave his body.
_thread->Wait(); //here current thread blocks
delete _thread; //safely delete thread
ps. method Delete() of wxThread class has quite confusing name, conformable to C++ delete operator name. it reality it's kinda(as i mentioned in another topic) "requestTheThreadToExit", which can be checked by requested thread via TestDestroy(). that's why a thread must periodically check TestDestroy() if there is such an external request
Last edited by alys666 on Thu May 16, 2019 10:41 am, edited 1 time in total.
ubuntu 16.04, wxWidgets 3.0.4

alys666
I live to help wx-kind
I live to help wx-kind
Posts: 186
Joined: Tue Oct 18, 2016 2:31 pm

Re: Thread deletion - where?

Post by alys666 » Thu May 16, 2019 10:32 am

it's crazy code, man.

Code: Select all

  
  if( m_db )
            std::lock_guard<std::mutex>( m_db->GetTableVector().my_mutex );
an idea of such a guards is simple.
in constructor some resource is allocated, opened, locked or something.
in destructor some resource is deallocated, closed, unlocked or something.
because C++ creates object at place of his declaration and destructs at block exiting, it serves for correct writing of such a sections of code - open/close, allocate/deallocate, lock/unlock, etc. No matter how this section was left(even by exception) - destructor will be called.
but in your code you just locked my_mutex, if (m_db) is true and immediately unlocked it.
you must use such a guards in this way

Code: Select all

{ //declare guarded region via brackets
 Guard _just_some_name(...); //declare guard object, here his ctor will be executed

}//end of quarged region, here the guard dtor will be executed, no matter how you exited this section
ubuntu 16.04, wxWidgets 3.0.4

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

Re: Thread deletion - where?

Post by doublemax » Thu May 16, 2019 10:54 am

The wxThread documentation shows how to properly destroy a detached thread:
https://docs.wxwidgets.org/trunk/classwx_thread.html
Use the source, Luke!

Post Reply