added wxQueueEvent() avoiding the bug of wxPostEvent() with the events having wxString fields

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53405 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-04-28 18:49:42 +00:00
parent d38e30d1d2
commit c3f941621e
4 changed files with 127 additions and 40 deletions

View File

@@ -439,7 +439,7 @@ public:
wxCommandEvent(const wxCommandEvent& event)
: wxEvent(event),
m_cmdString(event.m_cmdString.c_str()), // "thread-safe"
m_cmdString(event.m_cmdString),
m_commandInt(event.m_commandInt),
m_extraLong(event.m_extraLong),
m_clientData(event.m_clientData),
@@ -2276,7 +2276,9 @@ public:
void SetEvtHandlerEnabled(bool enabled) { m_enabled = enabled; }
bool GetEvtHandlerEnabled() const { return m_enabled; }
// process an event right now
// Process an event right now: this can only be called from the main
// thread, use QueueEvent() for scheduling the events for
// processing from other threads.
virtual bool ProcessEvent(wxEvent& event);
// Process an event by calling ProcessEvent and handling any exceptions
@@ -2285,8 +2287,25 @@ public:
// wouldn't correctly propagate to wxEventLoop.
bool SafelyProcessEvent(wxEvent& event);
// add an event to be processed later
virtual void AddPendingEvent(const wxEvent& event);
// Schedule the given event to be processed later. It takes ownership of
// the event pointer, i.e. it will be deleted later. This is safe to call
// from multiple threads although you still need to ensure that wxString
// fields of the event object are deep copies and not use the same string
// buffer as other wxString objects in this thread.
virtual void QueueEvent(wxEvent *event);
// Add an event to be processed later: notice that this function is not
// safe to call from threads other than main, use QueueEvent()
virtual void AddPendingEvent(const wxEvent& event)
{
// notice that the thread-safety problem comes from the fact that
// Clone() doesn't make deep copies of wxString fields of wxEvent
// object and so the same wxString could be used from both threads when
// the event object is destroyed in this one -- QueueEvent() avoids
// this problem as the event pointer is not used any more in this
// thread at all after it is called.
QueueEvent(event.Clone());
}
void ProcessPendingEvents();
@@ -2491,15 +2510,27 @@ private:
};
#endif // wxUSE_WEAKREF
// Post a message to the given eventhandler which will be processed during the
// next event loop iteration
// Post a message to the given event handler which will be processed during the
// next event loop iteration.
//
// Notice that this one is not thread-safe, use wxQueueEvent()
inline void wxPostEvent(wxEvtHandler *dest, const wxEvent& event)
{
wxCHECK_RET( dest, wxT("need an object to post event to in wxPostEvent") );
wxCHECK_RET( dest, "need an object to post event to" );
dest->AddPendingEvent(event);
}
// Wrapper around wxEvtHandler::QueueEvent(): adds an event for later
// processing, unlike wxPostEvent it is safe to use from different thread even
// for events with wxString members
inline void wxQueueEvent(wxEvtHandler *dest, wxEvent *event)
{
wxCHECK_RET( dest, "need an object to queue event for" );
dest->QueueEvent(event);
}
typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&);
typedef void (wxEvtHandler::*wxIdleEventFunction)(wxIdleEvent&);