// Purpose: interface of all thread-related wxWidgets classes
// Author: wxWidgets team
// RCS-ID: $Id$
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
Example:
@code
- extern const wxEventType wxEVT_COMMAND_MYTHREAD_UPDATE;
+ wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
class MyFrame : public wxFrame, public wxThreadHelper
{
...
void DoStartALongTask();
- void OnThreadUpdate(wxCommandEvent& evt);
+ void OnThreadUpdate(wxThreadEvent& evt);
void OnClose(wxCloseEvent& evt);
...
char m_data[1024];
wxCriticalSection m_dataCS; // protects field above
- DECLARE_EVENT_TABLE()
+ wxDECLARE_EVENT_TABLE();
};
- DEFINE_EVENT_TYPE(wxEVT_COMMAND_MYTHREAD_UPDATE)
- BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+ wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent)
+ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate)
EVT_CLOSE(MyFrame::OnClose)
- END_EVENT_TABLE()
+ wxEND_EVENT_TABLE()
void MyFrame::DoStartALongTask()
{
// VERY IMPORTANT: do not call any GUI function inside this
// function; rather use wxQueueEvent():
- wxQueueEvent(this, new wxCommandEvent(wxEVT_COMMAND_MYTHREAD_UPDATE));
+ wxQueueEvent(this, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_UPDATE));
// we used pointer 'this' assuming it's safe; see OnClose()
}
Destroy();
}
- void MyFrame::OnThreadUpdate(wxCommandEvent&evt)
+ void MyFrame::OnThreadUpdate(wxThreadEvent& evt)
{
// ...do something... e.g. m_pGauge->Pulse();
@library{wxbase}
@category{threading}
- @see wxThread
+ @see wxThread, wxThreadEvent
*/
class wxThreadHelper
{
*/
virtual ExitCode Entry() = 0;
+ /**
+ Callback called by Delete() before actually deleting the thread.
+
+ This function can be overridden by the derived class to perform some
+ specific task when the thread is gracefully destroyed. Notice that it
+ will be executed in the context of the thread that called Delete() and
+ <b>not</b> in this thread's context.
+
+ TestDestroy() will be true for the thread before OnDelete() gets
+ executed.
+
+ @since 2.9.2
+
+ @see OnKill()
+ */
+ virtual void OnDelete();
+
+ /**
+ Callback called by Kill() before actually killing the thread.
+
+ This function can be overridden by the derived class to perform some
+ specific task when the thread is terminated. Notice that it will be
+ executed in the context of the thread that called Kill() and <b>not</b>
+ in this thread's context.
+
+ @since 2.9.2
+
+ @see OnDelete()
+ */
+ virtual void OnKill();
+
/**
@deprecated
Use CreateThread() instead.
@library{wxbase}
@category{threading}
+ @note Critical sections can be used before the wxWidgets library is fully
+ initialized. In particular, it's safe to create global
+ wxCriticalSection instances.
+
@see wxThread, wxCondition, wxCriticalSectionLocker
*/
class wxCriticalSection
~wxCriticalSection();
/**
- Enter the critical section (same as locking a mutex).
-
+ Enter the critical section (same as locking a mutex): if another thread
+ has already entered it, this call will block until the other thread
+ calls Leave().
There is no error return for this function.
- After entering the critical section protecting some global
- data the thread running in critical section may safely use/modify it.
+
+ After entering the critical section protecting a data variable,
+ the thread running inside the critical section may safely use/modify it.
+
+ Note that entering the same critical section twice or more from the same
+ thread doesn't result in a deadlock; in this case in fact this function will
+ immediately return.
*/
void Enter();
@code
// declare a new type of event, to be used by our MyThread class:
- extern const wxEventType wxEVT_COMMAND_MYTHREAD_COMPLETED;
- extern const wxEventType wxEVT_COMMAND_MYTHREAD_UPDATE;
+ wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent);
+ wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
class MyFrame;
class MyThread : public wxThread
// a resume routine would be nearly identic to DoPauseThread()
void DoResumeThread() { ... }
- void OnThreadCompletion(wxCommandEvent&);
+ void OnThreadUpdate(wxThreadEvent&);
+ void OnThreadCompletion(wxThreadEvent&);
void OnClose(wxCloseEvent&);
protected:
MyThread *m_pThread;
wxCriticalSection m_pThreadCS; // protects the m_pThread pointer
- DECLARE_EVENT_TABLE()
+ wxDECLARE_EVENT_TABLE();
};
- BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_CLOSE(MyFrame::OnClose)
EVT_MENU(Minimal_Start, MyFrame::DoStartThread)
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate)
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_COMPLETED, MyFrame::OnThreadCompletion)
- END_EVENT_TABLE()
+ wxEND_EVENT_TABLE()
- DEFINE_EVENT_TYPE(wxEVT_COMMAND_MYTHREAD_COMPLETED)
- DEFINE_EVENT_TYPE(wxEVT_COMMAND_MYTHREAD_UPDATE)
+ wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent)
+ wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent)
void MyFrame::DoStartThread()
{
{
// ... do a bit of work...
- wxQueueEvent(m_pHandler, new wxCommandEvent(wxEVT_COMMAND_MYTHREAD_UPDATE));
+ wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_UPDATE));
}
// signal the event handler that this thread is going to be destroyed
// NOTE: here we assume that using the m_pHandler pointer is safe,
// (in this case this is assured by the MyFrame destructor)
- wxQueueEvent(m_pHandler, new wxCommandEvent(wxEVT_COMMAND_MYTHREAD_COMPLETED));
+ wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_COMPLETED));
return (wxThread::ExitCode)0; // success
}
m_pHandler->m_pThread = NULL;
}
- void MyFrame::OnThreadCompletion(wxCommandEvent&)
+ void MyFrame::OnThreadCompletion(wxThreadEvent&)
{
wxMessageOutputDebug().Printf("MYFRAME: MyThread exited!\n");
}
- void MyFrame::OnThreadUpdate(wxCommandEvent&)
+ void MyFrame::OnThreadUpdate(wxThreadEvent&)
{
wxMessageOutputDebug().Printf("MYFRAME: MyThread update...\n");
}
if (m_pThread) // does the thread still exist?
{
- m_out.Printf("MYFRAME: deleting thread");
+ wxMessageOutputDebug().Printf("MYFRAME: deleting thread");
if (m_pThread->Delete() != wxTHREAD_NO_ERROR )
wxLogError("Can't delete the thread!");
/**
Returns the platform specific thread ID of the current thread as a long.
+
This can be used to uniquely identify threads, even if they are not wxThreads.
+
+ @see GetMainId()
*/
static wxThreadIdType GetCurrentId();
*/
wxThreadKind GetKind() const;
+ /**
+ Returns the thread ID of the main thread.
+
+ @see IsMain()
+
+ @since 2.9.1
+ */
+ static wxThreadIdType GetMainId();
+
/**
Gets the priority of the thread, between zero and 100.
/**
Returns @true if the calling thread is the main application thread.
+
+ Main thread in the context of wxWidgets is the one which initialized
+ the library.
+
+ @see GetMainId(), GetCurrentId()
*/
static bool IsMain();
of detached threads.
This function can only be called from another thread context.
+
+ Finally, note that once a thread has completed and its Entry() function
+ returns, you cannot call Run() on it again (an assert will fail in debug
+ builds or @c wxTHREAD_RUNNING will be returned in release builds).
*/
wxThreadError Run();
Locks the mutex object.
This is equivalent to LockTimeout() with infinite timeout.
+ Note that if this mutex is already locked by the caller thread,
+ this function doesn't block but rather immediately returns.
+
@return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_DEAD_LOCK.
*/
wxMutexError Lock();