Merge lp:~pete-woods/gmenuharness/race-condition-fix into lp:gmenuharness

Proposed by Pete Woods
Status: Merged
Approved by: Pete Woods
Approved revision: 27
Merged at revision: 26
Proposed branch: lp:~pete-woods/gmenuharness/race-condition-fix
Merge into: lp:gmenuharness
Diff against target: 100 lines (+39/-19)
1 file modified
src/MenuMatcher.cpp (+39/-19)
To merge this branch: bzr merge lp:~pete-woods/gmenuharness/race-condition-fix
Reviewer Review Type Date Requested Status
Indicator Applet Developers Pending
Review via email: mp+303023@code.launchpad.net

Commit message

Work around initialisation race condition in GMenu

Description of the change

Work around initialisation race condition in GMenu

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/MenuMatcher.cpp'
2--- src/MenuMatcher.cpp 2015-09-01 09:52:39 +0000
3+++ src/MenuMatcher.cpp 2016-08-16 14:47:57 +0000
4@@ -19,6 +19,7 @@
5 #include <unity/gmenuharness/MenuMatcher.h>
6 #include <unity/gmenuharness/MatchUtils.h>
7
8+#include <chrono>
9 #include <iostream>
10
11 #include <gio/gio.h>
12@@ -110,6 +111,29 @@
13 shared_ptr<GMenuModel> m_menu;
14
15 map<string, shared_ptr<GActionGroup>> m_actions;
16+
17+ void createGmenu()
18+ {
19+ m_menu.reset(
20+ G_MENU_MODEL(
21+ g_dbus_menu_model_get(
22+ m_session.get(),
23+ m_parameters.p->m_busName.c_str(),
24+ m_parameters.p->m_menuObjectPath.c_str())),
25+ &g_object_deleter);
26+
27+ for (const auto& action : m_parameters.p->m_actions)
28+ {
29+ shared_ptr<GActionGroup> actionGroup(
30+ G_ACTION_GROUP(
31+ g_dbus_action_group_get(
32+ m_session.get(),
33+ m_parameters.p->m_busName.c_str(),
34+ action.second.c_str())),
35+ &g_object_deleter);
36+ m_actions[action.first] = actionGroup;
37+ }
38+ }
39 };
40
41 MenuMatcher::MenuMatcher(const Parameters& parameters) :
42@@ -123,25 +147,7 @@
43 &gdbus_connection_deleter);
44 g_dbus_connection_set_exit_on_close(p->m_session.get(), false);
45
46- p->m_menu.reset(
47- G_MENU_MODEL(
48- g_dbus_menu_model_get(
49- p->m_session.get(),
50- p->m_parameters.p->m_busName.c_str(),
51- p->m_parameters.p->m_menuObjectPath.c_str())),
52- &g_object_deleter);
53-
54- for (const auto& action : p->m_parameters.p->m_actions)
55- {
56- shared_ptr<GActionGroup> actionGroup(
57- G_ACTION_GROUP(
58- g_dbus_action_group_get(
59- p->m_session.get(),
60- p->m_parameters.p->m_busName.c_str(),
61- action.second.c_str())),
62- &g_object_deleter);
63- p->m_actions[action.first] = actionGroup;
64- }
65+ p->createGmenu();
66 }
67
68 MenuMatcher::~MenuMatcher()
69@@ -154,10 +160,16 @@
70 return *this;
71 }
72
73+static chrono::time_point<chrono::system_clock> oneSecondTimeout() {
74+ return chrono::system_clock::now() + chrono::seconds(1);
75+}
76+
77 void MenuMatcher::match(MatchResult& matchResult) const
78 {
79 vector<unsigned int> location;
80
81+ auto timeout = oneSecondTimeout();
82+
83 while (true)
84 {
85 MatchResult childMatchResult(matchResult.createChild());
86@@ -186,6 +198,14 @@
87 }
88 else
89 {
90+ if (chrono::system_clock::now() >= timeout)
91+ {
92+ // Start with a fresh menu to work around initialisation race condition in GMenu
93+ p->createGmenu();
94+
95+ timeout = oneSecondTimeout();
96+ }
97+
98 if (matchResult.hasTimedOut())
99 {
100 matchResult.merge(childMatchResult);

Subscribers

People subscribed via source and target branches