diff --git a/interface/wx/thread.h b/interface/wx/thread.h index e97b4a024c..63eb7a1ef6 100644 --- a/interface/wx/thread.h +++ b/interface/wx/thread.h @@ -51,8 +51,6 @@ enum wxCondError { m_mutex = mutex; m_condition = condition; - - Create(); } virtual ExitCode Entry() @@ -772,26 +770,17 @@ enum wxThreadError { 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!"); delete m_pThread; 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": - // at any moment the thread may cease to exist (because it completes its work). - // To avoid dangling pointers OnThreadExit() will set m_pThread - // to NULL when the thread dies. - } + // 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). + // To avoid dangling pointers OnThreadExit() will set m_pThread + // to NULL when the thread dies. } wxThread::ExitCode MyThread::Entry() @@ -932,8 +921,7 @@ enum wxThreadError All threads other than the "main application thread" (the one running wxApp::OnInit() or the one your main function runs in, for example) are - considered "secondary threads". These include all threads created by Create() - or the corresponding constructors. + considered "secondary threads". 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. @@ -985,7 +973,7 @@ public: /** This constructor creates a new detached (default) or joinable C++ 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: - @b wxTHREAD_DETACHED - Creates a detached thread. @@ -1012,7 +1000,13 @@ public: to it (Ignored on platforms that don't support setting it explicitly, 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 It is a good idea to explicitly specify a value as systems' @@ -1191,7 +1185,7 @@ public: 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 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). - It can only be set after calling Create() but before calling Run(). - The following symbolic constants can be used in addition to raw values in 0..100 range: - ::wxPRIORITY_MIN: 0 diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index 90d47a663e..c829a6f911 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -1107,6 +1107,14 @@ wxThreadError wxThread::Run() { 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, wxT("thread may only be started once after Create()") ); diff --git a/src/os2/thread.cpp b/src/os2/thread.cpp index 830595af2a..b17b17cb83 100644 --- a/src/os2/thread.cpp +++ b/src/os2/thread.cpp @@ -626,6 +626,14 @@ wxThreadError wxThread::Run() { 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 ) { // actually, it may be almost any state at all, not only STATE_RUNNING diff --git a/src/osx/carbon/thread.cpp b/src/osx/carbon/thread.cpp index e8ab4cd0fe..162346773d 100644 --- a/src/osx/carbon/thread.cpp +++ b/src/osx/carbon/thread.cpp @@ -656,6 +656,9 @@ bool wxThreadInternal::Create( wxThread *thread, unsigned int stackSize ) wxASSERT_MSG( m_state == STATE_NEW && !m_tid, wxT("Create()ing thread twice?") ); + if ( thread->IsDetached() ) + Detach(); + OSStatus err = noErr; m_thread = thread; @@ -868,13 +871,9 @@ wxThreadError wxThread::Create( unsigned int stackSize ) { wxCriticalSectionLocker lock(m_critsect); - if ( m_isDetached ) - m_internal->Detach() ; - if ( !m_internal->Create(this, stackSize) ) { m_internal->SetState( STATE_EXITED ); - return wxTHREAD_NO_RESOURCE; } @@ -885,6 +884,17 @@ wxThreadError wxThread::Run() { 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, wxT("must call wxThread::Create() first") ); diff --git a/src/unix/threadpsx.cpp b/src/unix/threadpsx.cpp index b0a2e54f9f..8f36dd3ba7 100644 --- a/src/unix/threadpsx.cpp +++ b/src/unix/threadpsx.cpp @@ -749,6 +749,8 @@ public: // id pthread_t GetId() const { return m_threadId; } pthread_t *GetIdPtr() { return &m_threadId; } + // "created" flag + bool WasCreated() const { return m_created; } // "cancelled" flag void SetCancelFlag() { m_cancelled = true; } bool WasCancelled() const { return m_cancelled; } @@ -779,6 +781,9 @@ private: wxThreadState m_state; // see wxThreadState enum 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 bool m_cancelled; @@ -958,6 +963,7 @@ void wxThreadInternal::Cleanup(wxThread *thread) wxThreadInternal::wxThreadInternal() { m_state = STATE_NEW; + m_created = false; m_cancelled = false; m_prio = wxPRIORITY_DEFAULT; m_threadId = 0; @@ -1097,6 +1103,7 @@ wxThreadError wxThreadInternal::Create(wxThread *thread, return wxTHREAD_NO_RESOURCE; } + m_created = true; return wxTHREAD_NO_ERROR; } @@ -1321,8 +1328,14 @@ wxThreadError wxThread::Run() { wxCriticalSectionLocker lock(m_critsect); - wxCHECK_MSG( m_internal->GetId(), wxTHREAD_MISC_ERROR, - wxT("must call wxThread::Create() first") ); + // Create the thread if it wasn't created yet with an explicit + // Create() call: + if ( !m_internal->WasCreated() ) + { + wxThreadError rv = m_internal->Create(this, 0); + if ( rv != wxTHREAD_NO_ERROR ) + return rv; + } return m_internal->Run(); }