After exploring many debugging outputs and gdb stack traces I realized that an accelerator was changed whenever the node of the xml tree that represented a specific menu widget was marked as “dirty”. In the process of merging the several xml trees a node could be set dirty depending on the command that represent. Some commands need to be synchronized; this sync is transferred to the node, for example in impl_bonobo_ui_sync_menu_state. But the problem that this function had was the chaotic addition of accelerators which made an expensive growth of structures, memory leaks included.
The patch respects the fact that we can have a widget with multiple accelerators and that the same accelerator can be added many times in the same accelerator group. The code only avoid the accelerator addition if it has been added previously to the same widget (which is the common case).
A chart with the difference of the old and new behaviour of component mail switching (200 switches).
After each switch, evo sleep, for avoiding the linux scheduler interference. Other charts didn’t take into account that, but it doesn’t matter, because the effects and conclusions were the same. For example, the following chart represents a massive 200-switching. The old version never stops growing and the new one become stable in a specific threshold, determined by the end of an epoch in the Linux scheduler (probably evo should be at the end of the runqueue, but starvation doesn’t happen).
* Edited * I’ve changed the patch because it had a little problem of memory leaking. Thanks Benoît Dejean for your remark!