Deallocate wxThreadSpecificInfo when wxThread ends.
Cleanup wxThreadSpecificInfo after wxThread::Entry returns to be more memory efficient. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74834 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -52,6 +52,13 @@ public:
|
|||||||
wxLocaleUntranslatedStrings untranslatedStrings;
|
wxLocaleUntranslatedStrings untranslatedStrings;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if wxUSE_THREADS
|
||||||
|
// Cleans up storage for the current thread. Should be called when a thread
|
||||||
|
// is being destroyed. If it's not called, the only bad thing that happens
|
||||||
|
// is that the memory is deallocated later, on process termination.
|
||||||
|
static void ThreadCleanUp();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxThreadSpecificInfo() : logger(NULL), loggingDisabled(false) {}
|
wxThreadSpecificInfo() : logger(NULL), loggingDisabled(false) {}
|
||||||
};
|
};
|
||||||
|
@@ -614,6 +614,8 @@ protected:
|
|||||||
// of this thread.
|
// of this thread.
|
||||||
virtual void *Entry() = 0;
|
virtual void *Entry() = 0;
|
||||||
|
|
||||||
|
// use this to call the Entry() virtual method
|
||||||
|
void *CallEntry();
|
||||||
|
|
||||||
// Callbacks which may be overridden by the derived class to perform some
|
// Callbacks which may be overridden by the derived class to perform some
|
||||||
// specific actions when the thread is deleted or killed. By default they
|
// specific actions when the thread is deleted or killed. By default they
|
||||||
|
@@ -342,8 +342,16 @@ wxSemaError wxSemaphore::Post()
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
|
#include "wx/private/threadinfo.h"
|
||||||
|
#include "wx/scopeguard.h"
|
||||||
|
|
||||||
void wxThread::Sleep(unsigned long milliseconds)
|
void wxThread::Sleep(unsigned long milliseconds)
|
||||||
{
|
{
|
||||||
wxMilliSleep(milliseconds);
|
wxMilliSleep(milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *wxThread::CallEntry()
|
||||||
|
{
|
||||||
|
wxON_BLOCK_EXIT0(wxThreadSpecificInfo::ThreadCleanUp);
|
||||||
|
return Entry();
|
||||||
|
}
|
||||||
|
@@ -28,11 +28,9 @@ namespace
|
|||||||
|
|
||||||
// All thread info objects are stored in a global list so that they are
|
// All thread info objects are stored in a global list so that they are
|
||||||
// freed when global objects are destroyed and no memory leaks are reported.
|
// freed when global objects are destroyed and no memory leaks are reported.
|
||||||
//
|
|
||||||
// TODO: This could be made more efficient by freeing g_thisThreadInfo when
|
|
||||||
// wxThread terminates.
|
|
||||||
wxCriticalSection g_csAllThreadInfos;
|
wxCriticalSection g_csAllThreadInfos;
|
||||||
wxVector< wxSharedPtr<wxThreadSpecificInfo> > g_allThreadInfos;
|
typedef wxVector< wxSharedPtr<wxThreadSpecificInfo> > wxAllThreadInfos;
|
||||||
|
wxAllThreadInfos g_allThreadInfos;
|
||||||
|
|
||||||
// Pointer to currenct thread's instance
|
// Pointer to currenct thread's instance
|
||||||
wxTLS_TYPE(wxThreadSpecificInfo*) g_thisThreadInfo;
|
wxTLS_TYPE(wxThreadSpecificInfo*) g_thisThreadInfo;
|
||||||
@@ -52,6 +50,26 @@ wxThreadSpecificInfo& wxThreadSpecificInfo::Get()
|
|||||||
return *wxTLS_VALUE(g_thisThreadInfo);
|
return *wxTLS_VALUE(g_thisThreadInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxThreadSpecificInfo::ThreadCleanUp()
|
||||||
|
{
|
||||||
|
if ( !wxTLS_VALUE(g_thisThreadInfo) )
|
||||||
|
return; // nothing to do, not used by this thread at all
|
||||||
|
|
||||||
|
// find this thread's instance in g_allThreadInfos and destroy it
|
||||||
|
wxCriticalSectionLocker lock(g_csAllThreadInfos);
|
||||||
|
for ( wxAllThreadInfos::iterator i = g_allThreadInfos.begin();
|
||||||
|
i != g_allThreadInfos.end();
|
||||||
|
++i )
|
||||||
|
{
|
||||||
|
if ( i->get() == wxTLS_VALUE(g_thisThreadInfo) )
|
||||||
|
{
|
||||||
|
g_allThreadInfos.erase(i);
|
||||||
|
wxTLS_VALUE(g_thisThreadInfo) = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#else // !wxUSE_THREADS
|
#else // !wxUSE_THREADS
|
||||||
|
|
||||||
wxThreadSpecificInfo& wxThreadSpecificInfo::Get()
|
wxThreadSpecificInfo& wxThreadSpecificInfo::Get()
|
||||||
|
@@ -125,7 +125,7 @@ void wxThreadPrivate::SprocStart(void *ptr)
|
|||||||
|
|
||||||
thr->p_internal->thread_id = getpid();
|
thr->p_internal->thread_id = getpid();
|
||||||
thr->p_internal->exit_status = 0;
|
thr->p_internal->exit_status = 0;
|
||||||
status = thr->Entry();
|
status = thr->CallEntry();
|
||||||
thr->Exit(status);
|
thr->Exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -571,7 +571,7 @@ THREAD_RETVAL wxThreadInternal::DoThreadStart(wxThread *thread)
|
|||||||
return THREAD_ERROR_EXIT;
|
return THREAD_ERROR_EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = wxPtrToUInt(thread->Entry());
|
rc = wxPtrToUInt(thread->CallEntry());
|
||||||
}
|
}
|
||||||
wxCATCH_ALL( wxTheApp->OnUnhandledException(); )
|
wxCATCH_ALL( wxTheApp->OnUnhandledException(); )
|
||||||
|
|
||||||
|
@@ -418,7 +418,7 @@ void wxThreadInternal::OS2ThreadStart( void * pParam )
|
|||||||
unsigned long ulHab;
|
unsigned long ulHab;
|
||||||
if (traits)
|
if (traits)
|
||||||
traits->InitializeGui(ulHab);
|
traits->InitializeGui(ulHab);
|
||||||
dwRet = (DWORD)pThread->Entry();
|
dwRet = (DWORD)pThread->CallEntry();
|
||||||
if (traits)
|
if (traits)
|
||||||
traits->TerminateGui(ulHab);
|
traits->TerminateGui(ulHab);
|
||||||
|
|
||||||
|
@@ -623,7 +623,7 @@ OSStatus wxThreadInternal::MacThreadStart(void *parameter)
|
|||||||
|
|
||||||
if ( !dontRunAtAll )
|
if ( !dontRunAtAll )
|
||||||
{
|
{
|
||||||
pthread->m_exitcode = thread->Entry();
|
pthread->m_exitcode = thread->CallEntry();
|
||||||
|
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(thread->m_critsect);
|
wxCriticalSectionLocker lock(thread->m_critsect);
|
||||||
|
@@ -864,7 +864,7 @@ void *wxThreadInternal::PthreadStart(wxThread *thread)
|
|||||||
|
|
||||||
wxTRY
|
wxTRY
|
||||||
{
|
{
|
||||||
pthread->m_exitcode = thread->Entry();
|
pthread->m_exitcode = thread->CallEntry();
|
||||||
|
|
||||||
wxLogTrace(TRACE_THREADS,
|
wxLogTrace(TRACE_THREADS,
|
||||||
wxT("Thread %p Entry() returned %lu."),
|
wxT("Thread %p Entry() returned %lu."),
|
||||||
|
Reference in New Issue
Block a user