Call wxThread::Create() from Run() automatically.

In the common case, when Run() is called immediately after Create() and
default stack size is used, it's unnecessarily verbose.  Just create the
thread in Run() if it wasn't done explicitly yet.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73999 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2013-05-16 14:15:46 +00:00
parent 0dd300cab5
commit 2e57ca641b
5 changed files with 60 additions and 29 deletions

View File

@@ -51,8 +51,6 @@ enum wxCondError
{ {
m_mutex = mutex; m_mutex = mutex;
m_condition = condition; m_condition = condition;
Create();
} }
virtual ExitCode Entry() virtual ExitCode Entry()
@@ -772,26 +770,17 @@ enum wxThreadError
{ {
m_pThread = new MyThread(this); m_pThread = new MyThread(this);
if ( m_pThread->Create() != wxTHREAD_NO_ERROR ) if ( m_pThread->Run() != wxTHREAD_NO_ERROR )
{ {
wxLogError("Can't create the thread!"); wxLogError("Can't create the thread!");
delete m_pThread; delete m_pThread;
m_pThread = NULL; m_pThread = NULL;
} }
else
{
if (m_pThread->Run() != wxTHREAD_NO_ERROR )
{
wxLogError("Can't create the thread!");
delete m_pThread;
m_pThread = NULL;
}
// after the call to wxThread::Run(), the m_pThread pointer is "unsafe": // after the call to wxThread::Run(), the m_pThread pointer is "unsafe":
// at any moment the thread may cease to exist (because it completes its work). // at any moment the thread may cease to exist (because it completes its work).
// To avoid dangling pointers OnThreadExit() will set m_pThread // To avoid dangling pointers OnThreadExit() will set m_pThread
// to NULL when the thread dies. // to NULL when the thread dies.
}
} }
wxThread::ExitCode MyThread::Entry() wxThread::ExitCode MyThread::Entry()
@@ -932,8 +921,7 @@ enum wxThreadError
All threads other than the "main application thread" (the one running All threads other than the "main application thread" (the one running
wxApp::OnInit() or the one your main function runs in, for example) are wxApp::OnInit() or the one your main function runs in, for example) are
considered "secondary threads". These include all threads created by Create() considered "secondary threads".
or the corresponding constructors.
GUI calls, such as those to a wxWindow or wxBitmap are explicitly not safe GUI calls, such as those to a wxWindow or wxBitmap are explicitly not safe
at all in secondary threads and could end your application prematurely. at all in secondary threads and could end your application prematurely.
@@ -985,7 +973,7 @@ public:
/** /**
This constructor creates a new detached (default) or joinable C++ This constructor creates a new detached (default) or joinable C++
thread object. It does not create or start execution of the real thread - thread object. It does not create or start execution of the real thread -
for this you should use the Create() and Run() methods. for this you should use the Run() method.
The possible values for @a kind parameters are: The possible values for @a kind parameters are:
- @b wxTHREAD_DETACHED - Creates a detached thread. - @b wxTHREAD_DETACHED - Creates a detached thread.
@@ -1012,7 +1000,13 @@ public:
to it (Ignored on platforms that don't support setting it explicitly, to it (Ignored on platforms that don't support setting it explicitly,
eg. Unix system without @c pthread_attr_setstacksize). eg. Unix system without @c pthread_attr_setstacksize).
If you do not specify the stack size,the system's default value is used. If you do not specify the stack size, the system's default value is used.
@note
It is not necessary to call this method since 2.9.5, Run() will create
the thread internally. You only need to call Create() if you need to do
something with the thread (e.g. pass its ID to an external library)
before it starts.
@warning @warning
It is a good idea to explicitly specify a value as systems' It is a good idea to explicitly specify a value as systems'
@@ -1191,7 +1185,7 @@ public:
wxThreadError Resume(); wxThreadError Resume();
/** /**
Starts the thread execution. Should be called after Create(). Starts the thread execution.
Note that once you Run() a @b detached thread, @e any function call you do Note that once you Run() a @b detached thread, @e any function call you do
on the thread pointer (you must allocate it on the heap) is @e "unsafe"; on the thread pointer (you must allocate it on the heap) is @e "unsafe";
@@ -1222,8 +1216,6 @@ public:
/** /**
Sets the priority of the thread, between 0 (lowest) and 100 (highest). Sets the priority of the thread, between 0 (lowest) and 100 (highest).
It can only be set after calling Create() but before calling Run().
The following symbolic constants can be used in addition to raw The following symbolic constants can be used in addition to raw
values in 0..100 range: values in 0..100 range:
- ::wxPRIORITY_MIN: 0 - ::wxPRIORITY_MIN: 0

View File

@@ -1107,6 +1107,14 @@ wxThreadError wxThread::Run()
{ {
wxCriticalSectionLocker lock(m_critsect); wxCriticalSectionLocker lock(m_critsect);
// Create the thread if it wasn't created yet with an explicit
// Create() call:
if ( !m_internal->GetHandle() )
{
if ( !m_internal->Create(this, 0) )
return wxTHREAD_NO_RESOURCE;
}
wxCHECK_MSG( m_internal->GetState() == STATE_NEW, wxTHREAD_RUNNING, wxCHECK_MSG( m_internal->GetState() == STATE_NEW, wxTHREAD_RUNNING,
wxT("thread may only be started once after Create()") ); wxT("thread may only be started once after Create()") );

View File

@@ -626,6 +626,14 @@ wxThreadError wxThread::Run()
{ {
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
// Create the thread if it wasn't created yet with an explicit
// Create() call:
if ( !m_internal->GetHandle() )
{
if ( !m_internal->Create(this, 0) )
return wxTHREAD_NO_RESOURCE;
}
if ( m_internal->GetState() != STATE_NEW ) if ( m_internal->GetState() != STATE_NEW )
{ {
// actually, it may be almost any state at all, not only STATE_RUNNING // actually, it may be almost any state at all, not only STATE_RUNNING

View File

@@ -656,6 +656,9 @@ bool wxThreadInternal::Create( wxThread *thread, unsigned int stackSize )
wxASSERT_MSG( m_state == STATE_NEW && !m_tid, wxASSERT_MSG( m_state == STATE_NEW && !m_tid,
wxT("Create()ing thread twice?") ); wxT("Create()ing thread twice?") );
if ( thread->IsDetached() )
Detach();
OSStatus err = noErr; OSStatus err = noErr;
m_thread = thread; m_thread = thread;
@@ -868,13 +871,9 @@ wxThreadError wxThread::Create( unsigned int stackSize )
{ {
wxCriticalSectionLocker lock(m_critsect); wxCriticalSectionLocker lock(m_critsect);
if ( m_isDetached )
m_internal->Detach() ;
if ( !m_internal->Create(this, stackSize) ) if ( !m_internal->Create(this, stackSize) )
{ {
m_internal->SetState( STATE_EXITED ); m_internal->SetState( STATE_EXITED );
return wxTHREAD_NO_RESOURCE; return wxTHREAD_NO_RESOURCE;
} }
@@ -885,6 +884,17 @@ wxThreadError wxThread::Run()
{ {
wxCriticalSectionLocker lock(m_critsect); wxCriticalSectionLocker lock(m_critsect);
// Create the thread if it wasn't created yet with an explicit
// Create() call:
if ( m_internal->GetId() == kInvalidID )
{
if ( !m_internal->Create(this, stackSize) )
{
m_internal->SetState( STATE_EXITED );
return wxTHREAD_NO_RESOURCE;
}
}
wxCHECK_MSG( m_internal->GetId(), wxTHREAD_MISC_ERROR, wxCHECK_MSG( m_internal->GetId(), wxTHREAD_MISC_ERROR,
wxT("must call wxThread::Create() first") ); wxT("must call wxThread::Create() first") );

View File

@@ -749,6 +749,8 @@ public:
// id // id
pthread_t GetId() const { return m_threadId; } pthread_t GetId() const { return m_threadId; }
pthread_t *GetIdPtr() { return &m_threadId; } pthread_t *GetIdPtr() { return &m_threadId; }
// "created" flag
bool WasCreated() const { return m_created; }
// "cancelled" flag // "cancelled" flag
void SetCancelFlag() { m_cancelled = true; } void SetCancelFlag() { m_cancelled = true; }
bool WasCancelled() const { return m_cancelled; } bool WasCancelled() const { return m_cancelled; }
@@ -779,6 +781,9 @@ private:
wxThreadState m_state; // see wxThreadState enum wxThreadState m_state; // see wxThreadState enum
int m_prio; // in wxWidgets units: from 0 to 100 int m_prio; // in wxWidgets units: from 0 to 100
// this flag is set when the thread was successfully created
bool m_created;
// this flag is set when the thread should terminate // this flag is set when the thread should terminate
bool m_cancelled; bool m_cancelled;
@@ -958,6 +963,7 @@ void wxThreadInternal::Cleanup(wxThread *thread)
wxThreadInternal::wxThreadInternal() wxThreadInternal::wxThreadInternal()
{ {
m_state = STATE_NEW; m_state = STATE_NEW;
m_created = false;
m_cancelled = false; m_cancelled = false;
m_prio = wxPRIORITY_DEFAULT; m_prio = wxPRIORITY_DEFAULT;
m_threadId = 0; m_threadId = 0;
@@ -1097,6 +1103,7 @@ wxThreadError wxThreadInternal::Create(wxThread *thread,
return wxTHREAD_NO_RESOURCE; return wxTHREAD_NO_RESOURCE;
} }
m_created = true;
return wxTHREAD_NO_ERROR; return wxTHREAD_NO_ERROR;
} }
@@ -1321,8 +1328,14 @@ wxThreadError wxThread::Run()
{ {
wxCriticalSectionLocker lock(m_critsect); wxCriticalSectionLocker lock(m_critsect);
wxCHECK_MSG( m_internal->GetId(), wxTHREAD_MISC_ERROR, // Create the thread if it wasn't created yet with an explicit
wxT("must call wxThread::Create() first") ); // Create() call:
if ( !m_internal->WasCreated() )
{
wxThreadError rv = m_internal->Create(this, 0);
if ( rv != wxTHREAD_NO_ERROR )
return rv;
}
return m_internal->Run(); return m_internal->Run();
} }