Ticket #11501 (closed defect: fixed)

Opened 3 years ago

Last modified 3 years ago

Fixed deadlock with pthread-implemented wxThread deletion.

Reported by: talon_karrde Owned by:
Priority: normal Milestone:
Component: base Version: 2.9-svn
Keywords: wxThread deadlock pthread unix Cc:
Blocked By: Patch: yes
Blocking:

Description

A deadlock occurs if one wxThread waits for another wxThread to finish in its destructor. Here's a sample code which demonstrates that:

class WorkerThread : public wxThread
{
public:
    WorkerThread()
    {
        this->pHelperThread = new HelperThread(this);
        this->pHelperThread->Create();
        this->pHelperThread->Run();
    }

    ~WorkerThread()
    {
        {
            wxCriticalSectionLocker cs(this->HelperThreadCS);
            if(this->pHelperThread) this->pHelperThread->Delete();
        }

        for(;;)
        {
            {
                wxCriticalSectionLocker cs(this->HelperThreadCS);
                if(this->pHelperThread == NULL) break;
            }
            wxThread::Yield();
        }
    }

    wxThread *pHelperThread;
    wxCriticalSection HelperThreadCS;
};

class HelperThread : public wxThread
{
public:
    HelperThread(WorkerThread *pParentThread) { this->pParentThread =
pParentThread; }
    ~HelperThread()
    {
        wxCriticalSectionLocker cs(pParentThread->HelperThreadCS);
        pParentThread->pHelperThread = NULL;
    }

    WorkerThread *pParentThread;
};

If WorkerThread finishes before HelperThread it attempts to delete it in its dtor and then wait for it to finish. WorkerThread's dtor, however, is executed while gs_mutexDeleteThread is locked, and HelperThread must acquire this mutex in order to clean up before exiting, which results in a deadlock.
I've attached a patch which simply calls the deleted wxThread's dtor before acquiring the mutex.

Attachments

pthread_deadlock.patch download (0.8 KB) - added by talon_karrde 3 years ago.

Change History

Changed 3 years ago by talon_karrde

Changed 3 years ago by talon_karrde

  • version set to 2.9-svn

Changed 3 years ago by VZ

  • status changed from new to closed
  • resolution set to fixed

(In [62781]) Don't lock global mutex when deleting wxThread to avoid deadlocks.

Calling out the user-defined wxThread dtor while holding gs_mutexDeleteThread
lock is a bad idea as it may result in deadlocks if the dtor deletes another
thread. Only lock the mutex directly before manipulating the data it protects.

Thanks to Neno Ganchev.

Closes #11501.

Note: See TracTickets for help on using tickets.