{
m_mutex = mutex;
m_condition = condition;
-
- Create();
}
virtual ExitCode Entry()
{
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()
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.
/**
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.
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'
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";
/**
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
{
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()") );
{
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
wxASSERT_MSG( m_state == STATE_NEW && !m_tid,
wxT("Create()ing thread twice?") );
+ if ( thread->IsDetached() )
+ Detach();
+
OSStatus err = noErr;
m_thread = thread;
{
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;
}
{
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") );
// 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; }
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;
wxThreadInternal::wxThreadInternal()
{
m_state = STATE_NEW;
+ m_created = false;
m_cancelled = false;
m_prio = wxPRIORITY_DEFAULT;
m_threadId = 0;
return wxTHREAD_NO_RESOURCE;
}
+ m_created = true;
return wxTHREAD_NO_ERROR;
}
{
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();
}