News:

Accounts with zero posts and zero activity during the last months will be deleted periodically to fight SPAM!

Main Menu

wx2.8.12, sending event cross threads are not safe in current CB source

Started by ollydbg, June 21, 2013, 02:32:41 AM

Previous topic - Next topic

ollydbg

There are two functions which can send events from a worker thread to main GUI.
wxPostEvent() and AddPendingEvent()

According to the discussions below:

I think there are many issues in our C::B source:

wxCommandEvent is not thread safe for its m_cmdString member, e.g.:
           
            wxString message;
            wxCommandEvent evt(...);
            evt.SetString(message.c_str());
            wxPostEvent(m_Parent, evt);

The code snippet is not thread safe, because "evt" and the cloned wxCommandEvent shared the same wxString member buffer.

CodeBlocksEvent is not thread safe, e.g. in cbthreadpool.cpp

      CodeBlocksEvent evt = CodeBlocksEvent(cbEVT_THREADTASK_ALLDONE, m_ID);
      wxPostEvent(m_pOwner, evt);

CodeBlocksEvent is a derived class from wxCommandEvent, and I don't see it Clone its m_strString.

3, I'm not sure PipedProcess class has such issue, because its related to send event cross processes.

Solution:
If the event need to carry wxString from worker thread to main GUI thread, we should implement a Clone method which deep copy its m_cmdString. Just like the new event type wxThreadEvent in wx 2.9.x.

Any comments.



If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

MortenMacFly

Quote from: ollydbg on June 21, 2013, 02:32:41 AM
Solution:
If the event need to carry wxString from worker thread to main GUI thread, we should implement a Clone method which deep copy its m_cmdString. Just like the new event type wxThreadEvent in wx 2.9.x.
Yes, we should always do. As a matter of fact, for wx events its a good thing to always implement the clone method once you are using member vars.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

ollydbg

Ok, this is the first draft patch. I add a new class named cbThreadEvent, which replace all the cross thread sending message from wxCommandEvent to cbThreadEvent. The patch also included an improved hook measure patch from: Performance measurement of all C::B event handlers
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

MortenMacFly

Quote from: ollydbg on June 21, 2013, 09:34:31 AM
Ok, this is the first draft patch.
Could you do a proper SVN based patch? This patch does not apply.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

golgepapaz

This ,
Quote from: MortenMacFly on June 21, 2013, 01:13:34 PM
Could you do a proper SVN based patch? This patch does not apply.

Won't it be proper that defining the event in sdk_events.h and sdk_events.cpp instead of
cclogger.cpp and it's own header?

Also about that profiling stuff, I don't want to pay for something that I don't need. This should be
optional.


MortenMacFly

Quote from: golgepapaz on June 21, 2013, 03:55:31 PM
Won't it be proper that defining the event in sdk_events.h and sdk_events.cpp instead of
cclogger.cpp and it's own header?
Its not meant to be captured form outside. CC is a plugin, not the SDK. So the event is in the correct place.

Quote from: golgepapaz on June 21, 2013, 03:55:31 PM
Also about that profiling stuff, I don't want to pay for something that I don't need. This should be
optional.
Its only for debugging atm and surely will be in #defines to be explicitly compiled in or even removed after all. Patches posted here are fr playing with and will be cleaned-up before application. Don't you worry...
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

golgepapaz

Quote from: MortenMacFly on June 21, 2013, 04:17:42 PM
Its not meant to be captured form outside. CC is a plugin, not the SDK. So the event is in the correct place.
I think it more of a general-purpose event than something exclusive to CC as the name
and the purpose suggest. Since we are stuck with wx2.8.12 for some time, I consider it a utility for
for developers who cannot use wxThreadEvent (I myself need it for example). There are many utility classes in the sdk like nullptr_t
cbThreadPool, cbAssert etc. I don't see why this should be different.

ollydbg

Note my patch is only a draft patch, which show the direction, but it surely need all your comments. So, thanks for all your comments.
@golgepapaz
I think a good place to put the new event in sdk_events.h and sdk_events.cpp. But for me, I just put it in a new file, because once I change the sdk_events.h, then I need to rebuild all my targets..... That's some times waste a lot of time.

I believe that sending event cross thread not only happens in CC.
About the performance measure on the event hooks, that's my direction to find a "hang" bug, because sometimes, my Codeblocks will hang for 2 or 3 seconds, so I would like to see which cause this hang issue. :)

@Morten, this is the patch against SVN.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

MortenMacFly

Quote from: ollydbg on June 21, 2013, 05:34:54 PM
@Morten, this is the patch against SVN.
OK, thanks for that - it applied safely.

However, having this applied the Spellchecker plugin does not compile anymore. The reason is that is derives directly from HookFunctorBase and therefore your newly introduced method "GetTypeName2 is not implemented as it is pure virtual.

This is (however) most likely a design issue in the SpellChecker plugin. I don't know the rationale for deriving directly from this class (probably due to the need to override "Call"?!), but IMHO that should not be done and needed.

Maybe danselmi can enlighten us...?! ;-)

EDIT: And its the same for the OccurrenceHighlighter plugin... :-/
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

oBFusCATed

Is OccurrenceHighlighter still needed? I don't see in the contrib subdir...
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

danselmi

spell checker plugin: [url="http://developer.berlios.de/projects/spellchecker/"]http://developer.berlios.de/projects/spellchecker/[/url]
nassi shneiderman plugin: [url="http://developer.berlios.de/projects/nassiplugin"]http://developer.berlios.de/projects/nassiplugin[/url]

danselmi

Quote from: oBFusCATed on June 26, 2013, 12:15:11 AM
Is OccurrenceHighlighter still needed? I don't see in the contrib subdir...

OccurrenceHighlighter is an addition to the occurrence highlighting implemented in the core. It is able to permanently (until the string gets removed from the list again) highlight strings in all editors. Not only the currently selected.

Should I add it into contrib subdir?
spell checker plugin: [url="http://developer.berlios.de/projects/spellchecker/"]http://developer.berlios.de/projects/spellchecker/[/url]
nassi shneiderman plugin: [url="http://developer.berlios.de/projects/nassiplugin"]http://developer.berlios.de/projects/nassiplugin[/url]

MortenMacFly

Quote from: danselmi on June 26, 2013, 12:58:52 AM
Should I add it into contrib subdir?
I think so, yes (in fact I was under the assumption its there already...). I find it quite useful!
And thanks for the fix, btw...
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

oBFusCATed

Quote from: danselmi on June 26, 2013, 12:58:52 AM
Should I add it into contrib subdir?
I'd say core and also extract the other highlight occurrence code from the sdk in it.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

ollydbg

Quote from: ollydbg on June 21, 2013, 05:34:54 PM
Note my patch is only a draft patch, which show the direction, but it surely need all your comments. So, thanks for all your comments.
@golgepapaz
I think a good place to put the new event in sdk_events.h and sdk_events.cpp. But for me, I just put it in a new file, because once I change the sdk_events.h, then I need to rebuild all my targets..... That's some times waste a lot of time.

I believe that sending event cross thread not only happens in CC.
Now, I add the class implementation in a cpp file.
This is a new patch ( I add a new cpp file in the SDK)
See attachment, any comments?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.