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);
...
DECLARE_EVENT_TABLE()
};
- DEFINE_EVENT_TYPE(wxEVT_COMMAND_MYTHREAD_UPDATE)
+ wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent)
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate)
EVT_CLOSE(MyFrame::OnClose)
// 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
{
~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:
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_COMPLETED, MyFrame::OnThreadCompletion)
END_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");
}
as MFC.
A workaround for some wxWidgets ports is calling wxMutexGUIEnter()
- before any GUI calls and then calling wxMutexGUILeave() afterwords. However,
- the recommended way is to simply process the GUI calls in the main thread
- through an event that is posted by wxQueueEvent().
+ before any GUI calls and then calling wxMutexGUILeave() afterwords.
+ However, the recommended way is to simply process the GUI calls in the main
+ thread through an event that is posted by wxQueueEvent().
This does not imply that calls to these classes are thread-safe, however,
as most wxWidgets classes are not thread-safe, including wxString.
/**
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();
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();
*/
bool wxIsMainThread();
+
+
/**
This function must be called when any thread other than the main GUI thread
wants to get access to the GUI library. This function will block the
@endcode
This function is only defined on platforms which support preemptive
- threads.
+ threads and only works under some ports (wxMSW currently).
@note Under GTK, no creation of top-level windows is allowed in any thread
but the main one.