Code: Select all
wxThread::ExitCode MyThread::Entry()
{
for (int n=0; n<1000; n++)
{
//this->Sleep(5);
wxString str = wxT("hhhh");
// notify the main thread
wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, NUMBER_UPDATE_ID );
event.SetInt(n);
if (n%2 == 0)
str[0] = wxT('0');
else
str[0] = wxT('1');
event.SetString(str.c_str());
m_parent->GetEventHandler()->AddPendingEvent( event );
}
return 0;
}
Code: Select all
event.SetString(str.c_str());
The code the GCC compiler generate here in-fact looks like below:
Code: Select all
construct a temp wxString say: tempStr from str.c_str(); //nRefs = 1
run the assignment operator function, so event.m_cmdString get assigned; //nRefs = 2
destroy the temp wxString, so nRefs return back to 1
Code: Select all
m_parent->GetEventHandler()->AddPendingEvent( event );
So, the wxString (event.m_cmdString) is still shared.[debug]> p event.m_cmdString.GetStringData()->nRefs
[debug]$12 = 2
The nRefs value will return to 1 if "event" de-constructed.
But what happens if the OS did a thread switch(scheduled) before "event" de-constructed, there are two things going to happen:
1, "event" de-constructed in the worker thread
2, the new cloned event get processed in the main GUI thread
I don't know what happens first, maybe, they will get concurrently running. So, this is a kind of thread safety issue? Right?
Finally, I think the only way is: we did a full deep copy of every thing in the AddPendingEvent() function? Looks like there is not such way in wx2.8.12.
In wx.2.9.x, we can use wxThreadEvent Class?