Merge lp:~unity-api-team/indicator-network/fix-gmainloop-syncing into lp:indicator-network/14.09

Proposed by Antti Kaijanmäki
Status: Merged
Approved by: Marcus Tomlinson
Approved revision: 469
Merged at revision: 462
Proposed branch: lp:~unity-api-team/indicator-network/fix-gmainloop-syncing
Merge into: lp:indicator-network/14.09
Prerequisite: lp:~unity-api-team/indicator-network/increase-dbus-timeouts
Diff against target: 1839 lines (+662/-302)
34 files modified
src/connectivity-cpp/dbus-cpp/services/nm.h (+2/-11)
src/connectivity-cpp/src/platform/nmofono/manager.cpp (+45/-40)
src/connectivity-cpp/src/platform/nmofono/manager.h (+4/-0)
src/connectivity-cpp/src/platform/nmofono/wifi/access-point.cpp (+21/-12)
src/connectivity-cpp/src/platform/nmofono/wifi/access-point.h (+49/-3)
src/connectivity-cpp/src/platform/nmofono/wifi/grouped-access-point.cpp (+5/-5)
src/connectivity-cpp/src/platform/nmofono/wifi/grouped-access-point.h (+1/-2)
src/connectivity-cpp/src/platform/nmofono/wifi/link.cpp (+19/-61)
src/indicator/CMakeLists.txt (+2/-3)
src/indicator/connectivity-service/connectivity-service.cpp (+21/-5)
src/indicator/connectivity-service/connectivity-service.h (+4/-1)
src/indicator/indicator-network-service.cpp (+2/-0)
src/indicator/menuitems/access-point-item.cpp (+64/-49)
src/indicator/menuitems/access-point-item.h (+44/-0)
src/indicator/modem-manager.cpp (+17/-5)
src/indicator/modem-manager.h (+11/-1)
src/indicator/modem.cpp (+114/-34)
src/indicator/modem.h (+4/-1)
src/indicator/quick-access-section.cpp (+23/-11)
src/indicator/quick-access-section.h (+4/-1)
src/indicator/root-state.cpp (+38/-9)
src/indicator/root-state.h (+4/-1)
src/indicator/sim-unlock-dialog.h (+3/-0)
src/indicator/wifi-link-item.cpp (+51/-22)
src/indicator/wifi-link-item.h (+43/-0)
src/indicator/wifi-section.cpp (+32/-8)
src/indicator/wifi-section.h (+1/-1)
src/indicator/wwan-link-item.cpp (+10/-2)
src/indicator/wwan-section.cpp (+8/-1)
src/indicator/wwan-section.h (+1/-1)
src/menumodel-cpp/gio-helpers/util.cpp (+10/-10)
src/menumodel-cpp/gio-helpers/util.h (+2/-2)
tests/unit/indicator/menuitems/CMakeLists.txt (+1/-0)
tests/unit/indicator/menuitems/test-access-point-item.cpp (+2/-0)
To merge this branch: bzr merge lp:~unity-api-team/indicator-network/fix-gmainloop-syncing
Reviewer Review Type Date Requested Status
Marcus Tomlinson (community) Approve
Charles Kerr (community) Approve
Review via email: mp+240044@code.launchpad.net

Commit message

* Fix GMainLoopDispatch dispatching ordering when
  called inside GMainLoop already
* Fix GMainLoopDispatch locking
* Force all signals from external (dbus-cpp) threads through
  GMainLoopDispatch

To post a comment you must log in.
Revision history for this message
Charles Kerr (charlesk) wrote :

I have mixed feelings about this patch.

The "big picture" is this is a step in the right direction and my vote is to approve. I don't like the technical debt being accrued here, but it's preferable to blocking Criticals on an even larger megapatch.

First, The "shared pimpl" idiom of thread safety here is interesting. It's generic enough that it can be (and is) applied liberally here, so that's useful. TBH though, it doesn't make sense to keep processing these signals after the outer object's been destroyed and I would have preferred another solution, e.g. GMainLoopDispatch's destructor calling g_signal_remove() after checking a lock guard to confirm that the func wasn't being called at the same time.

Second, the new comments sprinkled through the code "this must be called from GMainLoop", "these signals are already synced in main loop" etc. are red flags. There are a lot of them and they're hard to test... if there's no code making incorrect calls now (and how would we know for certian?) there surely will be in the future. I'd rather see either (a) a compile-time test of some kind, although I don't know how that would work, or (b) consistent thread rules applied through the code so that everyone knows what the rules of the road are.

Third, many of the ScopedConnections created by connect() are dropped on the floor. Since these connections' lambdas hold handles to the pimpl shared_ptrs, we need to be more careful about disconnecting them when the public objects are destroyed. My concern is that we don't wind up with ghost object chains that continue to process each other's signals.

Lastly (and superficially), I'd also like to see GMainLoopDispatch renamed MainLoopDispatch, since there's nothing intrinsic to glib about the idea. :)

review: Approve
Revision history for this message
Antti Kaijanmäki (kaijanmaki) wrote :

> The "big picture" is this is a step in the right direction and my vote is to
> approve. I don't like the technical debt being accrued here, but it's
> preferable to blocking Criticals on an even larger megapatch.

The MP tries to do minimal changes, but yet introduce the dispatching of all external signals through GMainLoopDispatch.

> First, The "shared pimpl" idiom of thread safety here is interesting. It's
> generic enough that it can be (and is) applied liberally here, so that's
> useful. TBH though, it doesn't make sense to keep processing these signals
> after the outer object's been destroyed and I would have preferred another
> solution, e.g. GMainLoopDispatch's destructor calling g_signal_remove() after
> checking a lock guard to confirm that the func wasn't being called at the same
> time.

please note that GMainLoopDispatch is not a long living object. It's destructor is not usable for virtually anything.

GMainLoopDispatch is destroyed as soon as it gets out of scope in which it was created. It only exists to offer easy interface to the static variables inside menumodel-cpp/gio-helpers/utils.cpp.

> Second, the new comments sprinkled through the code "this must be called from
> GMainLoop", "these signals are already synced in main loop" etc. are red
> flags. There are a lot of them and they're hard to test... if there's no code
> making incorrect calls now (and how would we know for certian?) there surely
> will be in the future. I'd rather see either (a) a compile-time test of some
> kind, although I don't know how that would work, or (b) consistent thread
> rules applied through the code so that everyone knows what the rules of the
> road are.

Yes. the problem here is that the code base did not rely on GMainLoop being around at all. This is the first step to more widely utilize GMainLoop. It's already agreed that we will create certain assertion directive that checks it is being called from GMainLoop main context. This directive can then be slapped through the codebase to verify that the precondition holds.

> Third, many of the ScopedConnections created by connect() are dropped on the
> floor. Since these connections' lambdas hold handles to the pimpl shared_ptrs,

The only lambdas holding pimpl shared_ptrs are the ones passed to GMainLoopDispatch and the lambdas are free'ed as soon as the dispatching is done.

> we need to be more careful about disconnecting them when the public objects
> are destroyed. My concern is that we don't wind up with ghost object chains
> that continue to process each other's signals.

We share the same concern. Next step on robusting the code base is to indeed to vefiry the lifecycles. Any connections that there are now in place or are missing are coming from the code base prior of this MP. And verifying and fixing possible issues is left for next iteration to keep the MP size and mental burden down.

> Lastly (and superficially), I'd also like to see GMainLoopDispatch renamed
> MainLoopDispatch, since there's nothing intrinsic to glib about the idea. :)

here we go again... ;)

Revision history for this message
Marcus Tomlinson (marcustomlinson) wrote :

Tested this on mako rtm 115, and it does fix the linked bug. Next we should scan through the rest of the code for callbacks that could arrive on external threads (E.g. service side writable properties whose 'changed' signals are emitted from the dbus-cpp thread)

review: Approve
468. By Antti Kaijanmäki

races races all the way..

469. By Antti Kaijanmäki

blah..

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/connectivity-cpp/dbus-cpp/services/nm.h'
2--- src/connectivity-cpp/dbus-cpp/services/nm.h 2014-10-31 14:07:40 +0000
3+++ src/connectivity-cpp/dbus-cpp/services/nm.h 2014-10-31 14:07:40 +0000
4@@ -911,7 +911,7 @@
5 return result.value();
6 }
7
8- std::vector<Device> get_devices()
9+ std::vector<core::dbus::types::ObjectPath> get_devices()
10 {
11 auto result =
12 object->invoke_method_synchronously<
13@@ -921,16 +921,7 @@
14 if (result.is_error())
15 connectivity::throw_dbus_exception(result.error());
16
17- std::vector<Device> devices;
18- for (const auto& path : result.value())
19- {
20- devices.emplace_back(
21- Device(
22- service,
23- service->object_for_path(path)));
24- }
25-
26- return devices;
27+ return result.value();
28 }
29
30 NetworkManager(std::shared_ptr<core::dbus::Service> &service,
31
32=== modified file 'src/connectivity-cpp/src/platform/nmofono/manager.cpp'
33--- src/connectivity-cpp/src/platform/nmofono/manager.cpp 2014-10-09 10:58:30 +0000
34+++ src/connectivity-cpp/src/platform/nmofono/manager.cpp 2014-10-31 14:07:40 +0000
35@@ -172,29 +172,11 @@
36 p->urfkill->switches[fdo::URfkill::Interface::Killswitch::Type::wlan]);
37 p->m_wifiKillSwitch->state().changed().connect(std::bind(&Private::updateHasWifi, p.get()));
38
39- p->nm->device_added->connect([this](const dbus::types::ObjectPath &path){
40-#ifdef INDICATOR_NETWORK_TRACE_MESSAGES
41- std::cout << "Device Added:" << path.as_string() << std::endl;
42-#endif
43- auto links = p->m_links.get();
44- for (const auto &dev : links) {
45- if (std::dynamic_pointer_cast<wifi::Link>(dev)->device_path() == path) {
46- // already in the list
47- return;
48- }
49- }
50-
51- NM::Interface::Device dev(p->nm->service,
52- p->nm->service->object_for_path(path));
53- if (dev.type() == NM::Interface::Device::Type::wifi) {
54- links.insert(std::make_shared<wifi::Link>(dev,
55- *p->nm.get(),
56- p->m_wifiKillSwitch));
57- p->m_links.set(links);
58- }
59-
60- p->updateHasWifi();
61- });
62+ p->nm->device_added->connect(std::bind(&Manager::device_added, this, std::placeholders::_1));
63+ for(const auto &path : p->nm->get_devices()) {
64+ device_added(path);
65+ }
66+
67 p->nm->device_removed->connect([this](const dbus::types::ObjectPath &path){
68 #ifdef INDICATOR_NETWORK_TRACE_MESSAGES
69 std::cout << "Device Removed:" << path.as_string() << std::endl;
70@@ -210,23 +192,6 @@
71
72 p->updateHasWifi();
73 });
74- std::set<std::shared_ptr<networking::Link> > links;
75- for(auto dev : p->nm->get_devices()) {
76- switch (dev.type()) {
77- case NM::Interface::Device::Type::wifi:
78- {
79- std::shared_ptr<networking::Link> link;
80- link.reset(new wifi::Link(dev,
81- *p->nm.get(),
82- p->m_wifiKillSwitch));
83- links.insert(link);
84- break;
85- }
86- default:
87- ;
88- }
89- }
90- p->m_links.set(links);
91
92 updateNetworkingStatus(p->nm->state->get());
93 p->nm->properties_changed->connect([this](NM::Interface::NetworkManager::Signal::PropertiesChanged::ArgumentType map) {
94@@ -259,6 +224,46 @@
95 }
96
97 void
98+Manager::device_added(const dbus::types::ObjectPath &path)
99+{
100+#ifdef INDICATOR_NETWORK_TRACE_MESSAGES
101+ std::cout << "Device Added:" << path.as_string() << std::endl;
102+#endif
103+ auto links = p->m_links.get();
104+
105+ for (const auto &dev : links) {
106+ if (std::dynamic_pointer_cast<wifi::Link>(dev)->device_path() == path) {
107+ // already in the list
108+ return;
109+ }
110+ }
111+
112+ connectivity::networking::Link::Ptr link;
113+ try {
114+ NM::Interface::Device dev(p->nm->service,
115+ p->nm->service->object_for_path(path));
116+ if (dev.type() == NM::Interface::Device::Type::wifi) {
117+ link = std::make_shared<wifi::Link>(dev,
118+ *p->nm.get(),
119+ p->m_wifiKillSwitch);
120+ }
121+ } catch (const std::exception &e) {
122+ std::cerr << __PRETTY_FUNCTION__ << ": failed to create Device proxy for "<< path.as_string() << ": " << std::endl
123+ << "\t" << e.what() << std::endl
124+ << "\tIgnoring." << std::endl;
125+ return;
126+ }
127+
128+ if (link) {
129+ links.insert(link);
130+ p->m_links.set(links);
131+ }
132+
133+ p->updateHasWifi();
134+}
135+
136+
137+void
138 Manager::enableFlightMode()
139 {
140 #ifdef INDICATOR_NETWORK_TRACE_MESSAGES
141
142=== modified file 'src/connectivity-cpp/src/platform/nmofono/manager.h'
143--- src/connectivity-cpp/src/platform/nmofono/manager.h 2014-09-25 00:06:12 +0000
144+++ src/connectivity-cpp/src/platform/nmofono/manager.h 2014-10-31 14:07:40 +0000
145@@ -20,6 +20,7 @@
146 #define PLATFORM_NMOFONO_MANAGER
147
148 #include <connectivity/networking/manager.h>
149+#include <core/dbus/types/object_path.h>
150
151 namespace core {
152 namespace dbus {
153@@ -61,6 +62,9 @@
154 const core::Property<std::set<std::shared_ptr<connectivity::networking::Service>>>&services() const override;
155 const core::Property<connectivity::networking::Manager::NetworkingStatus> & status() const override;
156 const core::Property<std::uint32_t>& characteristics() const override;
157+
158+private:
159+ void device_added(const core::dbus::types::ObjectPath &path);
160 };
161
162 #endif
163
164=== modified file 'src/connectivity-cpp/src/platform/nmofono/wifi/access-point.cpp'
165--- src/connectivity-cpp/src/platform/nmofono/wifi/access-point.cpp 2014-08-22 12:18:55 +0000
166+++ src/connectivity-cpp/src/platform/nmofono/wifi/access-point.cpp 2014-10-31 14:07:40 +0000
167@@ -34,11 +34,11 @@
168
169 std::string ssid;
170 // Note: raw_ssid is _not_ guaranteed to be null terminated.
171- const std::vector<std::int8_t> &raw_ssid = m_ap.ssid->get();
172- if(g_utf8_validate((const char*)(&raw_ssid[0]), raw_ssid.size(), nullptr)) {
173- ssid = std::string(raw_ssid.begin(), raw_ssid.end());
174+ m_raw_ssid = m_ap.ssid->get();
175+ if(g_utf8_validate((const char*)(&m_raw_ssid[0]), m_raw_ssid.size(), nullptr)) {
176+ ssid = std::string(m_raw_ssid.begin(), m_raw_ssid.end());
177 } else {
178- for (auto c : m_ap.ssid->get()) {
179+ for (auto c : m_raw_ssid) {
180 if (isprint(c)) {
181 ssid += (char)c;
182 } else {
183@@ -58,6 +58,15 @@
184 }
185 }
186 });
187+
188+ m_flags = m_ap.flags->get();
189+ /* NetworkManager seems to set the wpa and rns flags
190+ * for AccessPoints on the same network in a total random manner.
191+ * Sometimes only wpa_flags or rns_flags is set and sometimes
192+ * they both are set but always to the same value
193+ */
194+ m_secflags = m_ap.wpa_flags->get()|m_ap.rsn_flags->get();
195+ m_mode = m_ap.mode->get();
196 }
197
198 const core::dbus::types::ObjectPath AccessPoint::object_path() const {
199@@ -79,6 +88,11 @@
200 return m_ssid;
201 }
202
203+const std::vector<std::int8_t>& AccessPoint::raw_ssid() const
204+{
205+ return m_raw_ssid;
206+}
207+
208 bool AccessPoint::secured() const
209 {
210 return m_secured;
211@@ -93,14 +107,9 @@
212 if(this == &other)
213 return true;
214 return m_ssid == other.m_ssid &&
215- m_ap.flags->get() == other.m_ap.flags->get() &&
216- /* NetworkManager seems to set the wpa and rns flags
217- * for AccessPoints on the same network in a total random manner.
218- * Sometimes only wpa_flags or rns_flags is set and sometimes
219- * they both are set but always to the same value
220- */
221- (m_ap.wpa_flags->get()|m_ap.rsn_flags->get()) == (other.m_ap.wpa_flags->get()|other.m_ap.rsn_flags->get()) &&
222- m_ap.mode->get() == other.m_ap.mode->get();
223+ m_flags == other.m_flags &&
224+ m_secflags == other.m_secflags &&
225+ m_mode == other.m_mode;
226 }
227
228 }
229
230=== modified file 'src/connectivity-cpp/src/platform/nmofono/wifi/access-point.h'
231--- src/connectivity-cpp/src/platform/nmofono/wifi/access-point.h 2014-08-19 19:55:15 +0000
232+++ src/connectivity-cpp/src/platform/nmofono/wifi/access-point.h 2014-10-31 14:07:40 +0000
233@@ -40,10 +40,52 @@
234
235 class AccessPoint : public connectivity::networking::wifi::AccessPoint
236 {
237-
238 public:
239 typedef std::shared_ptr<AccessPoint> Ptr;
240
241+ struct Key {
242+ std::string ssid;
243+ uint32_t flags;
244+ uint32_t secflags;
245+ uint32_t mode;
246+
247+ bool operator<(const Key &other) const
248+ {
249+ // Standard lexigraphic comparison.
250+ if(ssid < other.ssid)
251+ return true;
252+ if(ssid > other.ssid)
253+ return false;
254+
255+ if(flags < other.flags)
256+ return true;
257+ if(flags > other.flags)
258+ return false;
259+
260+ if(secflags < other.secflags)
261+ return true;
262+ if(secflags > secflags)
263+ return false;
264+
265+ if(mode < other.mode)
266+ return true;
267+ if(mode > other.mode)
268+ return false;
269+ return false;
270+ }
271+
272+ Key() = delete;
273+ Key(const AccessPoint::Ptr &curap)
274+ {
275+ ssid = curap->ssid();
276+ flags = curap->m_flags;
277+ secflags = curap->m_secflags;
278+ mode = curap->m_mode;
279+ }
280+ };
281+ friend class Key;
282+
283+
284 AccessPoint(const org::freedesktop::NetworkManager::Interface::AccessPoint &ap);
285 const core::Property<double>& strength() const;
286 virtual ~AccessPoint() = default;
287@@ -54,6 +96,7 @@
288 const core::Property<std::chrono::system_clock::time_point>& lastConnected() const;
289
290 const std::string& ssid() const override;
291+ const std::vector<std::int8_t>& raw_ssid() const;
292
293 bool secured() const override;
294
295@@ -61,8 +104,6 @@
296
297 const core::dbus::types::ObjectPath object_path() const;
298
299- const org::freedesktop::NetworkManager::Interface::AccessPoint& get_ap() const { return m_ap; }
300-
301 bool operator==(const platform::nmofono::wifi::AccessPoint &other) const;
302 bool operator!=(const platform::nmofono::wifi::AccessPoint &other) const { return !(*this == other); };
303
304@@ -71,8 +112,13 @@
305 core::Property<std::chrono::system_clock::time_point> m_lastConnected;
306 org::freedesktop::NetworkManager::Interface::AccessPoint m_ap;
307 std::string m_ssid;
308+ std::vector<std::int8_t> m_raw_ssid;
309 bool m_secured;
310 bool m_adhoc;
311+
312+ std::uint32_t m_flags;
313+ std::uint32_t m_secflags;
314+ std::uint32_t m_mode;
315 };
316
317 }
318
319=== modified file 'src/connectivity-cpp/src/platform/nmofono/wifi/grouped-access-point.cpp'
320--- src/connectivity-cpp/src/platform/nmofono/wifi/grouped-access-point.cpp 2014-10-09 10:58:30 +0000
321+++ src/connectivity-cpp/src/platform/nmofono/wifi/grouped-access-point.cpp 2014-10-31 14:07:40 +0000
322@@ -156,11 +156,6 @@
323 return p->aplist.at(0)->object_path();
324 }
325
326-const org::freedesktop::NetworkManager::Interface::AccessPoint& GroupedAccessPoint::get_ap() const {
327- std::lock_guard<std::mutex> l(p->m);
328- return p->aplist.at(0)->get_ap();
329-}
330-
331 const core::Property<double>& GroupedAccessPoint::strength() const
332 {
333 std::lock_guard<std::mutex> l(p->m);
334@@ -177,7 +172,12 @@
335 {
336 std::lock_guard<std::mutex> l(p->m);
337 return p->aplist.at(0)->ssid();
338+}
339
340+const std::vector<std::int8_t>& GroupedAccessPoint::raw_ssid() const
341+{
342+ std::lock_guard<std::mutex> l(p->m);
343+ return p->aplist.at(0)->raw_ssid();
344 }
345
346 bool GroupedAccessPoint::secured() const
347
348=== modified file 'src/connectivity-cpp/src/platform/nmofono/wifi/grouped-access-point.h'
349--- src/connectivity-cpp/src/platform/nmofono/wifi/grouped-access-point.h 2014-08-19 19:55:15 +0000
350+++ src/connectivity-cpp/src/platform/nmofono/wifi/grouped-access-point.h 2014-10-31 14:07:40 +0000
351@@ -57,6 +57,7 @@
352 const core::Property<std::chrono::system_clock::time_point>& lastConnected() const;
353
354 const std::string& ssid() const override;
355+ const std::vector<std::int8_t>& raw_ssid() const;
356
357 bool secured() const override;
358
359@@ -64,8 +65,6 @@
360
361 const core::dbus::types::ObjectPath object_path() const;
362
363- const org::freedesktop::NetworkManager::Interface::AccessPoint& get_ap() const;
364-
365 void add_ap(std::shared_ptr<platform::nmofono::wifi::AccessPoint> &ap);
366 void remove_ap(std::shared_ptr<platform::nmofono::wifi::AccessPoint> &ap);
367 int num_aps() const;
368
369=== modified file 'src/connectivity-cpp/src/platform/nmofono/wifi/link.cpp'
370--- src/connectivity-cpp/src/platform/nmofono/wifi/link.cpp 2014-10-09 10:58:30 +0000
371+++ src/connectivity-cpp/src/platform/nmofono/wifi/link.cpp 2014-10-31 14:07:40 +0000
372@@ -30,58 +30,6 @@
373
374 using core::Property;
375
376-struct AccessPointKey {
377- std::string ssid;
378- uint32_t flags;
379- uint32_t wpa_flags;
380- uint32_t rsn_flags;
381- uint32_t mode;
382-
383- bool operator<(const AccessPointKey &other) const
384- {
385- // Standard lexigraphic comparison.
386- if(ssid < other.ssid)
387- return true;
388- if(ssid > other.ssid)
389- return false;
390-
391- if(flags < other.flags)
392- return true;
393- if(flags > other.flags)
394- return false;
395-
396- /* NetworkManager seems to set the wpa and rns flags
397- * for AccessPoints on the same network in a total random manner.
398- * Sometimes only wpa_flags or rns_flags is set and sometimes
399- * they both are set but always to the same value
400- */
401- if((wpa_flags|rsn_flags) < (other.wpa_flags|other.rsn_flags))
402- return true;
403- if((wpa_flags|rsn_flags) > (other.wpa_flags|other.rsn_flags))
404- return false;
405-
406- if(mode < other.mode)
407- return true;
408- if(mode > other.mode)
409- return false;
410- return false;
411- }
412-};
413-
414-namespace {
415-
416-AccessPointKey build_key(const std::shared_ptr<platform::nmofono::wifi::AccessPoint> &curap)
417-{
418- AccessPointKey k;
419- k.ssid = curap->ssid();
420- k.flags = curap->get_ap().flags->get();
421- k.wpa_flags = curap->get_ap().wpa_flags->get();
422- k.rsn_flags = curap->get_ap().rsn_flags->get();
423- k.mode = curap->get_ap().mode->get();
424- return k;
425-}
426-
427-}
428
429 struct Link::Private
430 {
431@@ -103,7 +51,7 @@
432 // hack hack
433 std::vector<core::ScopedConnection> switchConnection;
434
435- std::map<AccessPointKey, std::shared_ptr<GroupedAccessPoint>> grouper;
436+ std::map<AccessPoint::Key, std::shared_ptr<GroupedAccessPoint>> grouper;
437 bool disabled;
438 std::uint32_t lastState;
439 std::string name;
440@@ -165,13 +113,23 @@
441 return;
442 }
443 }
444+
445+ platform::nmofono::wifi::AccessPoint::Ptr shap;
446+ try {
447+ NM::Interface::AccessPoint ap(p->nm.service->object_for_path(path));
448+ shap = std::make_shared<platform::nmofono::wifi::AccessPoint>(ap);
449+ } catch(const std::exception &e) {
450+ std::cerr << __PRETTY_FUNCTION__ << ": failed to create AccessPoint proxy for "<< path.as_string() << ": " << std::endl
451+ << "\t" << e.what() << std::endl
452+ << "\tIgnoring." << std::endl;
453+ return;
454+ }
455+
456 auto list = p->rawAccessPoints.get();
457- NM::Interface::AccessPoint ap(p->nm.service->object_for_path(path));
458- auto shap = std::make_shared<platform::nmofono::wifi::AccessPoint>(ap);
459 list.insert(shap);
460 p->rawAccessPoints.set(list);
461
462- auto k = build_key(shap);
463+ auto k = AccessPoint::Key(shap);
464 if(p->grouper.find(k) != p->grouper.end()) {
465 p->grouper[k]->add_ap(shap);
466 } else {
467@@ -200,7 +158,7 @@
468 }
469 }
470 if (!shap) {
471- std::cerr << "Tried to remove access point " << path.as_string() << " that has not been added." << std::endl;
472+ std::cerr << __PRETTY_FUNCTION__ << ": Tried to remove access point " << path.as_string() << " that has not been added." << std::endl;
473 return;
474 }
475 p->rawAccessPoints.set(list);
476@@ -345,11 +303,11 @@
477 // The accesspoint interface does not provide this property so we need to coax it out of
478 // derived classes.
479 if(ap) {
480- ssid = ap->get_ap().ssid->get();
481+ ssid = ap->raw_ssid();
482 } else {
483 std::shared_ptr<AccessPoint> bap = std::dynamic_pointer_cast<AccessPoint>(accessPoint);
484 assert(bap);
485- ssid = bap->get_ap().ssid->get();
486+ ssid = bap->raw_ssid();
487 }
488 NM::Interface::Connection *found = nullptr;
489 auto connections = p->dev.get_available_connections();
490@@ -360,7 +318,7 @@
491 if (conf.first == "ssid") {
492 std::vector<int8_t> value;
493 value = conf.second.as<std::vector<std::int8_t>>();
494- if (value == ap->get_ap().ssid->get()) {
495+ if (value == ap->raw_ssid()) {
496 found = &con;
497 break;
498 }
499@@ -384,7 +342,7 @@
500 /// @todo getting the ssid multiple times over dbus is stupid.
501
502 std::map<std::string, dbus::types::Variant> wireless_conf;
503- wireless_conf["ssid"] = dbus::types::Variant::encode<std::vector<std::int8_t>>(ap->get_ap().ssid->get());
504+ wireless_conf["ssid"] = dbus::types::Variant::encode<std::vector<std::int8_t>>(ap->raw_ssid());
505
506 conf["802-11-wireless"] = wireless_conf;
507 auto ret = p->nm.add_and_activate_connection(conf,
508
509=== modified file 'src/indicator/CMakeLists.txt'
510--- src/indicator/CMakeLists.txt 2014-08-19 21:03:04 +0000
511+++ src/indicator/CMakeLists.txt 2014-10-31 14:07:40 +0000
512@@ -7,19 +7,18 @@
513 service.h
514 indicator-menu.h
515 modem.cpp
516- modem.h
517 modem-manager.cpp
518 quick-access-section.cpp
519 sim-unlock-dialog.cpp
520 root-state.cpp
521- wifi-link-item.h
522+ wifi-link-item.cpp
523 wifi-section.cpp
524 wwan-link-item.cpp
525 wwan-section.cpp
526
527 connectivity-service/connectivity-service.cpp
528
529- menuitems/access-point-item.h
530+ menuitems/access-point-item.cpp
531 menuitems/item.h
532 menuitems/modem-info-item.cpp
533 menuitems/section.h
534
535=== modified file 'src/indicator/connectivity-service/connectivity-service.cpp'
536--- src/indicator/connectivity-service/connectivity-service.cpp 2014-09-12 10:51:35 +0000
537+++ src/indicator/connectivity-service/connectivity-service.cpp 2014-10-31 14:07:40 +0000
538@@ -20,6 +20,8 @@
539 #include "connectivity-service.h"
540 #include <dbus-cpp/services/connectivity.h>
541
542+#include <menumodel-cpp/gio-helpers/util.h>
543+
544 #include <core/dbus/asio/executor.h>
545 #include <core/dbus/helper/type_mapper.h>
546
547@@ -81,7 +83,7 @@
548 };
549 }
550
551-class ConnectivityService::Private
552+class ConnectivityService::Private : public std::enable_shared_from_this<Private>
553 {
554 public:
555 std::thread m_connectivityServiceWorker;
556@@ -105,6 +107,7 @@
557
558 Private() = delete;
559 Private(std::shared_ptr<networking::Manager> manager);
560+ void ConstructL();
561 ~Private();
562
563 void updateNetworkingStatus();
564@@ -114,9 +117,18 @@
565
566 ConnectivityService::Private::Private(std::shared_ptr<networking::Manager> manager)
567 : m_manager{manager}
568+{}
569+
570+void
571+ConnectivityService::Private::ConstructL()
572 {
573- m_manager->characteristics().changed().connect(std::bind(&Private::updateNetworkingStatus, this));
574- m_manager->status().changed().connect(std::bind(&Private::updateNetworkingStatus, this));
575+ auto that = shared_from_this();
576+ m_manager->characteristics().changed().connect(
577+ [that](int){ GMainLoopDispatch([that](){ that->updateNetworkingStatus(); }); });
578+
579+ typedef connectivity::networking::Manager::NetworkingStatus NetworkingStatus;
580+ m_manager->status().changed().connect(
581+ [that](NetworkingStatus){ GMainLoopDispatch([that](){ that->updateNetworkingStatus(); }); });
582
583 m_bus = std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::session);
584
585@@ -185,7 +197,9 @@
586 {
587 auto reply = core::dbus::Message::make_method_return(msg);
588 m_bus->send(reply);
589- m_unlockAllModems();
590+
591+ auto that = shared_from_this();
592+ GMainLoopDispatch([that](){ that->m_unlockAllModems(); });
593 });
594 }
595
596@@ -306,7 +320,9 @@
597
598 ConnectivityService::ConnectivityService(std::shared_ptr<networking::Manager> manager)
599 : d{new Private(manager)}
600-{}
601+{
602+ d->ConstructL();
603+}
604
605 ConnectivityService::~ConnectivityService()
606 {}
607
608=== modified file 'src/indicator/connectivity-service/connectivity-service.h'
609--- src/indicator/connectivity-service/connectivity-service.h 2014-08-07 23:00:39 +0000
610+++ src/indicator/connectivity-service/connectivity-service.h 2014-10-31 14:07:40 +0000
611@@ -29,11 +29,14 @@
612 ConnectivityService(std::shared_ptr<connectivity::networking::Manager> manager);
613 virtual ~ConnectivityService();
614
615+ /**
616+ * synced with GMainLoop
617+ */
618 core::Signal<> &unlockAllModems();
619
620 private:
621 class Private;
622- std::unique_ptr<Private> d;
623+ std::shared_ptr<Private> d;
624 };
625
626 #endif
627
628=== modified file 'src/indicator/indicator-network-service.cpp'
629--- src/indicator/indicator-network-service.cpp 2014-08-15 11:52:50 +0000
630+++ src/indicator/indicator-network-service.cpp 2014-10-31 14:07:40 +0000
631@@ -86,6 +86,8 @@
632
633 std::shared_ptr<Service> menu {new Service(manager)};
634 std::unique_ptr<ConnectivityService> connectivityService {new ConnectivityService(manager)};
635+
636+ // unlockAllModems is dispatched from GMainLoop
637 connectivityService->unlockAllModems().connect([menu](){ menu->unlockAllModems(); });
638
639 if (getenv("VALGRIND") != 0) {
640
641=== renamed file 'src/indicator/menuitems/access-point-item.h' => 'src/indicator/menuitems/access-point-item.cpp'
642--- src/indicator/menuitems/access-point-item.h 2014-08-15 11:49:44 +0000
643+++ src/indicator/menuitems/access-point-item.cpp 2014-10-31 14:07:40 +0000
644@@ -17,32 +17,42 @@
645 * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
646 */
647
648-#ifndef ACCESS_POINT_ITEM_H
649-#define ACCESS_POINT_ITEM_H
650+#include "access-point-item.h"
651
652-#include "item.h"
653 #include "menumodel-cpp/action.h"
654 #include "menumodel-cpp/menu-item.h"
655 #include "menumodel-cpp/gio-helpers/variant.h"
656
657-#include <core/signal.h>
658-
659-#include <connectivity/networking/wifi/access-point.h>
660 namespace networking = connectivity::networking;
661
662 #include <functional>
663 #include <vector>
664
665-class AccessPointItem : public Item
666+class AccessPointItem::Private : public std::enable_shared_from_this<Private>
667 {
668-
669 public:
670- typedef std::shared_ptr<AccessPointItem> Ptr;
671-
672- AccessPointItem() = delete;
673- explicit AccessPointItem(networking::wifi::AccessPoint::Ptr accessPoint, bool isActive = false)
674- : m_accessPoint{accessPoint},
675+ AccessPointItem *q;
676+
677+ networking::wifi::AccessPoint::Ptr m_accessPoint;
678+ bool m_isActive;
679+
680+ core::Signal<void> m_activated;
681+
682+ std::vector<core::Connection> m_connections;
683+
684+ Action::Ptr m_actionActivate;
685+ Action::Ptr m_actionStrength;
686+ MenuItem::Ptr m_item;
687+
688+
689+ Private() = delete;
690+ explicit Private(AccessPointItem *parent, networking::wifi::AccessPoint::Ptr accessPoint, bool isActive = false)
691+ : q{parent},
692+ m_accessPoint{accessPoint},
693 m_isActive{isActive}
694+ {}
695+
696+ void ConstructL()
697 {
698 static int id = 0;
699 ++id; /// @todo guard me.
700@@ -64,9 +74,17 @@
701 nullptr,
702 TypedVariant<std::uint8_t>(m_accessPoint->strength().get()));
703
704- auto con = m_accessPoint->strength().changed().connect(std::bind(&AccessPointItem::setStrength,
705- this,
706- std::placeholders::_1));
707+ auto weak = std::weak_ptr<Private>(shared_from_this());
708+ auto con = m_accessPoint->strength().changed().connect([weak](double value)
709+ {
710+ auto that = weak.lock();
711+ if (!that)
712+ return;
713+ GMainLoopDispatch([that, value]()
714+ {
715+ that->setStrength(value);
716+ });
717+ });
718 m_connections.push_back(con);
719
720 m_actionActivate = std::make_shared<Action>(actionId,
721@@ -79,11 +97,11 @@
722 m_activated();
723 });
724
725- m_actionGroup->add(m_actionActivate);
726- m_actionGroup->add(m_actionStrength);
727+ q->actionGroup()->add(m_actionActivate);
728+ q->actionGroup()->add(m_actionStrength);
729 }
730
731- virtual ~AccessPointItem()
732+ virtual ~Private()
733 {
734 for (auto con : m_connections)
735 con.disconnect();
736@@ -94,35 +112,32 @@
737 /// @todo narrow_cast<>;
738 m_actionStrength->setState(TypedVariant<std::uint8_t>(value));
739 }
740-
741- void setActive(bool value)
742- {
743- m_isActive = value;
744- m_actionActivate->setState(TypedVariant<bool>(m_isActive));
745- }
746-
747- virtual MenuItem::Ptr
748- menuItem()
749- {
750- return m_item;
751- }
752-
753- core::Signal<void> &activated()
754- {
755- return m_activated;
756- }
757-
758-private:
759- networking::wifi::AccessPoint::Ptr m_accessPoint;
760- bool m_isActive;
761-
762- core::Signal<void> m_activated;
763-
764- std::vector<core::Connection> m_connections;
765-
766- Action::Ptr m_actionActivate;
767- Action::Ptr m_actionStrength;
768- MenuItem::Ptr m_item;
769 };
770
771-#endif // ACCESS_POINT_ITEM_H
772+AccessPointItem::AccessPointItem(networking::wifi::AccessPoint::Ptr accessPoint, bool isActive)
773+ : d{new Private(this, accessPoint, isActive)}
774+{
775+ d->ConstructL();
776+}
777+
778+AccessPointItem::~AccessPointItem()
779+{}
780+
781+void
782+AccessPointItem::setActive(bool value)
783+{
784+ d->m_isActive = value;
785+ d->m_actionActivate->setState(TypedVariant<bool>(d->m_isActive));
786+}
787+
788+MenuItem::Ptr
789+AccessPointItem::menuItem()
790+{
791+ return d->m_item;
792+}
793+
794+core::Signal<void> &
795+AccessPointItem::activated()
796+{
797+ return d->m_activated;
798+}
799
800=== added file 'src/indicator/menuitems/access-point-item.h'
801--- src/indicator/menuitems/access-point-item.h 1970-01-01 00:00:00 +0000
802+++ src/indicator/menuitems/access-point-item.h 2014-10-31 14:07:40 +0000
803@@ -0,0 +1,44 @@
804+/*
805+ * Copyright (C) 2014 Canonical, Ltd.
806+ *
807+ * This program is free software: you can redistribute it and/or modify it
808+ * under the terms of the GNU General Public License version 3, as published
809+ * by the Free Software Foundation.
810+ *
811+ * This program is distributed in the hope that it will be useful, but
812+ * WITHOUT ANY WARRANTY; without even the implied warranties of
813+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
814+ * PURPOSE. See the GNU General Public License for more details.
815+ *
816+ * You should have received a copy of the GNU General Public License along
817+ * with this program. If not, see <http://www.gnu.org/licenses/>.
818+ *
819+ * Authors:
820+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
821+ */
822+
823+#ifndef ACCESS_POINT_ITEM_H
824+#define ACCESS_POINT_ITEM_H
825+
826+#include <connectivity/networking/wifi/access-point.h>
827+#include "item.h"
828+
829+class AccessPointItem : public Item
830+{
831+ class Private;
832+ std::shared_ptr<Private> d;
833+
834+public:
835+ typedef std::shared_ptr<AccessPointItem> Ptr;
836+
837+ AccessPointItem() = delete;
838+ explicit AccessPointItem(connectivity::networking::wifi::AccessPoint::Ptr accessPoint, bool isActive = false);
839+ virtual ~AccessPointItem();
840+
841+ void setActive(bool value);
842+
843+ virtual MenuItem::Ptr menuItem();
844+ core::Signal<void> &activated();
845+};
846+
847+#endif // ACCESS_POINT_ITEM_H
848
849=== modified file 'src/indicator/modem-manager.cpp'
850--- src/indicator/modem-manager.cpp 2014-10-15 11:31:13 +0000
851+++ src/indicator/modem-manager.cpp 2014-10-31 14:07:40 +0000
852@@ -19,6 +19,8 @@
853
854 #include "modem-manager.h"
855
856+#include <menumodel-cpp/gio-helpers/util.h>
857+
858 #include <notify-cpp/snapdecision/sim-unlock.h>
859
860 #include "dbus-cpp/services/ofono.h"
861@@ -30,7 +32,7 @@
862
863 #include "sim-unlock-dialog.h"
864
865-class ModemManager::Private
866+class ModemManager::Private : public std::enable_shared_from_this<Private>
867 {
868 public:
869
870@@ -47,6 +49,10 @@
871 std::list<Modem::Ptr> m_pendingUnlocks;
872
873 Private()
874+ {}
875+
876+ void
877+ ConstructL()
878 {
879 m_bus = std::make_shared<core::dbus::Bus>(core::dbus::WellKnownBus::system);
880
881@@ -83,8 +89,10 @@
882 ofono_disappeared();
883 }
884 m_watcher = m_dbus->make_service_watcher(org::ofono::Service::name());
885- m_watcher->service_registered().connect([this]() { ofono_appeared(); });
886- m_watcher->service_unregistered().connect([this](){ ofono_disappeared(); });
887+
888+ auto that = shared_from_this();
889+ m_watcher->service_registered().connect([that](){ GMainLoopDispatch([that](){ that->ofono_appeared(); }); });
890+ m_watcher->service_unregistered().connect([that](){ GMainLoopDispatch([that](){ that->ofono_disappeared(); }); });
891 }
892
893 ~Private()
894@@ -109,7 +117,10 @@
895 std::cerr << e.what() << std::endl;
896 }
897
898- m_ofono->manager->modems.changed().connect(std::bind(&Private::modems_changed, this, std::placeholders::_1));
899+ auto that = shared_from_this();
900+ m_ofono->manager->modems.changed().connect(
901+ [that](std::map<core::dbus::types::ObjectPath, org::ofono::Interface::Modem::Ptr> modems)
902+ { GMainLoopDispatch([that, modems]() { that->modems_changed(modems); }); });
903 modems_changed(m_ofono->manager->modems.get());
904 }
905
906@@ -171,8 +182,9 @@
907 };
908
909 ModemManager::ModemManager()
910+ : d{new Private}
911 {
912- d.reset(new Private);
913+ d->ConstructL();
914 }
915
916 ModemManager::~ModemManager()
917
918=== modified file 'src/indicator/modem-manager.h'
919--- src/indicator/modem-manager.h 2014-08-07 20:24:48 +0000
920+++ src/indicator/modem-manager.h 2014-10-31 14:07:40 +0000
921@@ -28,7 +28,7 @@
922 class ModemManager
923 {
924 class Private;
925- std::unique_ptr<Private> d;
926+ std::shared_ptr<Private> d;
927
928 public:
929
930@@ -37,9 +37,19 @@
931 ModemManager();
932 ~ModemManager();
933
934+ /**
935+ * must be called from GMainLoop
936+ */
937 void unlockModem(Modem::Ptr modem);
938+
939+ /**
940+ * must be called from GMainLoop
941+ */
942 void unlockAllModems();
943
944+ /**
945+ * changed() emitted from GMainLoop
946+ */
947 const core::Property<std::set<Modem::Ptr>> &modems();
948 };
949
950
951=== modified file 'src/indicator/modem.cpp'
952--- src/indicator/modem.cpp 2014-10-08 09:45:57 +0000
953+++ src/indicator/modem.cpp 2014-10-31 14:07:40 +0000
954@@ -19,7 +19,9 @@
955
956 #include "modem.h"
957
958-class Modem::Private
959+#include <menumodel-cpp/gio-helpers/util.h>
960+
961+class Modem::Private : public std::enable_shared_from_this<Private>
962 {
963 public:
964 core::Property<bool> m_online;
965@@ -41,8 +43,60 @@
966 void simManagerChanged(org::ofono::Interface::SimManager::Ptr simmgr);
967
968 void update();
969+
970+ Private() = delete;
971+ Private(org::ofono::Interface::Modem::Ptr ofonoModem);
972+ void ConstructL();
973 };
974
975+Modem::Private::Private(org::ofono::Interface::Modem::Ptr ofonoModem)
976+ : m_ofonoModem{ofonoModem}
977+{}
978+
979+void
980+Modem::Private::ConstructL()
981+{
982+ auto that = shared_from_this();
983+
984+ m_online.set(m_ofonoModem->online.get());
985+ m_ofonoModem->online.changed().connect([that](bool value){
986+ GMainLoopDispatch([that, value]() {
987+ that->m_online.set(value);
988+ });
989+ });
990+
991+ simManagerChanged(m_ofonoModem->simManager.get());
992+ m_ofonoModem->simManager.changed().connect([that](org::ofono::Interface::SimManager::Ptr simmgr)
993+ {
994+ GMainLoopDispatch([that, simmgr](){
995+ that->simManagerChanged(simmgr);
996+ });
997+ });
998+
999+ networkRegistrationChanged(m_ofonoModem->networkRegistration.get());
1000+ m_ofonoModem->networkRegistration.changed().connect([that](org::ofono::Interface::NetworkRegistration::Ptr netreg)
1001+ {
1002+ GMainLoopDispatch([that, netreg](){
1003+ that->networkRegistrationChanged(netreg);
1004+ });
1005+ });
1006+
1007+ /// @todo hook up with system-settings to allow changing the identifier.
1008+ /// for now just provide the defaults
1009+ const auto path = m_ofonoModem->object->path().as_string();
1010+ if (path == "/ril_0") {
1011+ m_simIdentifier.set("SIM 1");
1012+ m_index = 1;
1013+ } else if (path == "/ril_1") {
1014+ m_simIdentifier.set("SIM 2");
1015+ m_index = 2;
1016+ } else {
1017+ m_simIdentifier.set(path);
1018+ }
1019+
1020+}
1021+
1022+
1023 void
1024 Modem::Private::update()
1025 {
1026@@ -119,10 +173,38 @@
1027 Modem::Private::networkRegistrationChanged(org::ofono::Interface::NetworkRegistration::Ptr netreg)
1028 {
1029 if (netreg) {
1030- netreg->operatorName.changed().connect(std::bind(&Private::update, this));
1031- netreg->status.changed().connect(std::bind(&Private::update, this));
1032- netreg->strength.changed().connect(std::bind(&Private::update, this));
1033- netreg->technology.changed().connect(std::bind(&Private::update, this));
1034+ auto that = shared_from_this();
1035+ netreg->operatorName.changed().connect([that](const std::string &)
1036+ {
1037+ GMainLoopDispatch([that]()
1038+ {
1039+ that->update();
1040+ });
1041+ });
1042+ netreg->status.changed().connect([that](org::ofono::Interface::NetworkRegistration::Status)
1043+ {
1044+ GMainLoopDispatch([that]()
1045+ {
1046+ that->update();
1047+ });
1048+ });
1049+
1050+ netreg->strength.changed().connect([that](std::int8_t)
1051+ {
1052+ GMainLoopDispatch([that]()
1053+ {
1054+ that->update();
1055+ });
1056+ });
1057+
1058+ netreg->technology.changed().connect([that](org::ofono::Interface::NetworkRegistration::Technology)
1059+ {
1060+ GMainLoopDispatch([that]()
1061+ {
1062+ that->update();
1063+ });
1064+ });
1065+
1066 }
1067 update();
1068 }
1069@@ -132,41 +214,39 @@
1070 Modem::Private::simManagerChanged(org::ofono::Interface::SimManager::Ptr simmgr)
1071 {
1072 if (simmgr) {
1073- simmgr->present.changed().connect(std::bind(&Private::update, this));
1074- simmgr->pinRequired.changed().connect(std::bind(&Private::update, this));
1075- simmgr->retries.changed().connect(std::bind(&Private::update, this));
1076+ auto that = shared_from_this();
1077+ simmgr->present.changed().connect([that](bool)
1078+ {
1079+ GMainLoopDispatch([that]()
1080+ {
1081+ that->update();
1082+ });
1083+ });
1084+
1085+ simmgr->pinRequired.changed().connect([that](org::ofono::Interface::SimManager::PinType)
1086+ {
1087+ GMainLoopDispatch([that]()
1088+ {
1089+ that->update();
1090+ });
1091+ });
1092+
1093+ simmgr->retries.changed().connect([that](std::map<org::ofono::Interface::SimManager::PinType, std::uint8_t>)
1094+ {
1095+ GMainLoopDispatch([that]()
1096+ {
1097+ that->update();
1098+ });
1099+ });
1100+
1101 }
1102 update();
1103 }
1104
1105 Modem::Modem(org::ofono::Interface::Modem::Ptr ofonoModem)
1106+ : d{new Private(ofonoModem)}
1107 {
1108- d.reset(new Private);
1109- d->m_ofonoModem = ofonoModem;
1110-
1111- d->m_online.set(d->m_ofonoModem->online.get());
1112- d->m_ofonoModem->online.changed().connect([this](bool value){
1113- d->m_online.set(value);
1114- });
1115-
1116- d->simManagerChanged(d->m_ofonoModem->simManager.get());
1117- d->m_ofonoModem->simManager.changed().connect(std::bind(&Private::simManagerChanged, d.get(), std::placeholders::_1));
1118-
1119- d->networkRegistrationChanged(d->m_ofonoModem->networkRegistration.get());
1120- d->m_ofonoModem->networkRegistration.changed().connect(std::bind(&Private::networkRegistrationChanged, d.get(), std::placeholders::_1));
1121-
1122- /// @todo hook up with system-settings to allow changing the identifier.
1123- /// for now just provide the defaults
1124- const auto path = ofonoModem->object->path().as_string();
1125- if (path == "/ril_0") {
1126- d->m_simIdentifier.set("SIM 1");
1127- d->m_index = 1;
1128- } else if (path == "/ril_1") {
1129- d->m_simIdentifier.set("SIM 2");
1130- d->m_index = 2;
1131- } else {
1132- d->m_simIdentifier.set(path);
1133- }
1134+ d->ConstructL();
1135 }
1136
1137 Modem::~Modem()
1138
1139=== modified file 'src/indicator/modem.h'
1140--- src/indicator/modem.h 2014-10-02 11:36:00 +0000
1141+++ src/indicator/modem.h 2014-10-31 14:07:40 +0000
1142@@ -27,10 +27,13 @@
1143
1144 #include "dbus-cpp/services/ofono.h"
1145
1146+/**
1147+ * all signals and property changes emitted from GMainLoop
1148+ */
1149 class Modem
1150 {
1151 class Private;
1152- std::unique_ptr<Private> d;
1153+ std::shared_ptr<Private> d;
1154
1155 public:
1156 enum class PinType
1157
1158=== modified file 'src/indicator/quick-access-section.cpp'
1159--- src/indicator/quick-access-section.cpp 2014-10-09 10:58:30 +0000
1160+++ src/indicator/quick-access-section.cpp 2014-10-31 14:07:40 +0000
1161@@ -26,7 +26,7 @@
1162
1163 namespace networking = connectivity::networking;
1164
1165-class QuickAccessSection::Private
1166+class QuickAccessSection::Private : public std::enable_shared_from_this<Private>
1167 {
1168 public:
1169 ActionGroupMerger::Ptr m_actionGroupMerger;
1170@@ -36,15 +36,23 @@
1171
1172 SwitchItem::Ptr m_flightModeSwitch;
1173
1174+ Private() = delete;
1175 Private(std::shared_ptr<networking::Manager> manager);
1176+ void ConstructL();
1177 };
1178
1179 QuickAccessSection::Private::Private(std::shared_ptr<networking::Manager> manager)
1180 : m_manager{manager}
1181+{}
1182+
1183+void
1184+QuickAccessSection::Private::ConstructL()
1185 {
1186 m_actionGroupMerger = std::make_shared<ActionGroupMerger>();
1187 m_menu = std::make_shared<Menu>();
1188
1189+ auto that = shared_from_this();
1190+
1191 m_flightModeSwitch = std::make_shared<SwitchItem>(_("Flight Mode"), "airplane", "enabled");
1192 switch (m_manager->flightMode().get()) {
1193 case networking::Manager::FlightModeStatus::off:
1194@@ -54,15 +62,18 @@
1195 m_flightModeSwitch->state().set(true);
1196 break;
1197 }
1198- m_manager->flightMode().changed().connect([this](networking::Manager::FlightModeStatus value){
1199- switch (value) {
1200- case networking::Manager::FlightModeStatus::off:
1201- m_flightModeSwitch->state().set(false);
1202- break;
1203- case networking::Manager::FlightModeStatus::on:
1204- m_flightModeSwitch->state().set(true);
1205- break;
1206- }
1207+ m_manager->flightMode().changed().connect([that](networking::Manager::FlightModeStatus value){
1208+ GMainLoopDispatch([that, value]
1209+ {
1210+ switch (value) {
1211+ case networking::Manager::FlightModeStatus::off:
1212+ that->m_flightModeSwitch->state().set(false);
1213+ break;
1214+ case networking::Manager::FlightModeStatus::on:
1215+ that->m_flightModeSwitch->state().set(true);
1216+ break;
1217+ }
1218+ });
1219 });
1220 m_flightModeSwitch->activated().connect([this](){
1221 if (m_flightModeSwitch->state().get()) {
1222@@ -85,8 +96,9 @@
1223 }
1224
1225 QuickAccessSection::QuickAccessSection(std::shared_ptr<networking::Manager> manager)
1226+ : d{new Private(manager)}
1227 {
1228- d.reset(new Private(manager));
1229+ d->ConstructL();
1230 }
1231
1232 QuickAccessSection::~QuickAccessSection()
1233
1234=== modified file 'src/indicator/quick-access-section.h'
1235--- src/indicator/quick-access-section.h 2014-04-23 14:41:46 +0000
1236+++ src/indicator/quick-access-section.h 2014-10-31 14:07:40 +0000
1237@@ -23,10 +23,13 @@
1238 #include "menuitems/section.h"
1239 #include <connectivity/networking/manager.h>
1240
1241+/**
1242+ * all signals and property changes emitted from GMainLoop
1243+ */
1244 class QuickAccessSection : public Section
1245 {
1246 class Private;
1247- std::unique_ptr<Private> d;
1248+ std::shared_ptr<Private> d;
1249
1250 public:
1251 typedef std::shared_ptr<QuickAccessSection> Ptr;
1252
1253=== modified file 'src/indicator/root-state.cpp'
1254--- src/indicator/root-state.cpp 2014-10-06 08:30:34 +0000
1255+++ src/indicator/root-state.cpp 2014-10-31 14:07:40 +0000
1256@@ -24,9 +24,11 @@
1257 #include <connectivity/networking/wifi/link.h>
1258 #include <connectivity/networking/wifi/access-point.h>
1259
1260+#include <menumodel-cpp/gio-helpers/util.h>
1261+
1262 namespace networking = connectivity::networking;
1263
1264-class RootState::Private
1265+class RootState::Private : public std::enable_shared_from_this<Private>
1266 {
1267 public:
1268 std::shared_ptr<networking::Manager> m_manager;
1269@@ -43,6 +45,7 @@
1270
1271 Private() = delete;
1272 Private(std::shared_ptr<networking::Manager> manager, ModemManager::Ptr modemManager);
1273+ void ConstructL();
1274
1275 void modemsChanged(const std::set<Modem::Ptr> &modems);
1276
1277@@ -57,14 +60,38 @@
1278 RootState::Private::Private(std::shared_ptr<networking::Manager> manager, ModemManager::Ptr modemManager)
1279 : m_manager{manager},
1280 m_modemManager{modemManager}
1281-{
1282- m_manager->flightMode().changed().connect(std::bind(&Private::updateRootState, this));
1283-
1284+{}
1285+
1286+void
1287+RootState::Private::ConstructL()
1288+{
1289+ auto that = shared_from_this();
1290+
1291+ m_manager->flightMode().changed().connect([that](connectivity::networking::Manager::FlightModeStatus)
1292+ {
1293+ GMainLoopDispatch([that](){
1294+ that->updateRootState();
1295+ });
1296+ });
1297+
1298+ modemsChanged(m_modemManager->modems().get());
1299+ // modem properties and signals already synced with GMainLoop
1300 m_modemManager->modems().changed().connect(std::bind(&Private::modemsChanged, this, std::placeholders::_1));
1301- modemsChanged(m_modemManager->modems().get());
1302-
1303- m_manager->status().changed().connect(std::bind(&Private::updateNetworkingIcon, this));
1304- m_manager->links().changed().connect(std::bind(&Private::updateNetworkingIcon, this));
1305+
1306+ m_manager->status().changed().connect([that](connectivity::networking::Manager::NetworkingStatus)
1307+ {
1308+ GMainLoopDispatch([that](){
1309+ that->updateNetworkingIcon();
1310+ });
1311+ });
1312+
1313+ m_manager->links().changed().connect([that](std::set<connectivity::networking::Link::Ptr>)
1314+ {
1315+ GMainLoopDispatch([that](){
1316+ that->updateNetworkingIcon();
1317+ });
1318+ });
1319+
1320
1321 // will also call updateRootState()
1322 updateNetworkingIcon();
1323@@ -90,6 +117,7 @@
1324 m_cellularIcons.erase(modem);
1325
1326 for (auto modem : added) {
1327+ // modem properties and signals already synced with GMainLoop
1328 modem->online().changed().connect(std::bind(&Private::updateModem, this, Modem::WeakPtr(modem)));
1329 modem->simStatus().changed().connect(std::bind(&Private::updateModem, this, Modem::WeakPtr(modem)));
1330 modem->status().changed().connect(std::bind(&Private::updateModem, this, Modem::WeakPtr(modem)));
1331@@ -319,8 +347,9 @@
1332 }
1333
1334 RootState::RootState(std::shared_ptr<connectivity::networking::Manager> manager, ModemManager::Ptr modemManager)
1335+ : d{new Private(manager, modemManager)}
1336 {
1337- d.reset(new Private(manager, modemManager));
1338+ d->ConstructL();
1339 }
1340
1341 RootState::~RootState()
1342
1343=== modified file 'src/indicator/root-state.h'
1344--- src/indicator/root-state.h 2014-05-12 11:36:59 +0000
1345+++ src/indicator/root-state.h 2014-10-31 14:07:40 +0000
1346@@ -25,10 +25,13 @@
1347
1348 #include "menumodel-cpp/gio-helpers/variant.h"
1349
1350+/**
1351+ * all signals and property changes emitted from GMainLoop
1352+ */
1353 class RootState
1354 {
1355 class Private;
1356- std::unique_ptr<Private> d;
1357+ std::shared_ptr<Private> d;
1358
1359 public:
1360 typedef std::shared_ptr<RootState> Ptr;
1361
1362=== modified file 'src/indicator/sim-unlock-dialog.h'
1363--- src/indicator/sim-unlock-dialog.h 2014-10-14 19:54:51 +0000
1364+++ src/indicator/sim-unlock-dialog.h 2014-10-31 14:07:40 +0000
1365@@ -23,6 +23,9 @@
1366 #include <memory>
1367 #include "modem.h"
1368
1369+/**
1370+ * all signals and property changes dispatched from GMainLoop
1371+ */
1372 class SimUnlockDialog
1373 {
1374 class Private;
1375
1376=== renamed file 'src/indicator/wifi-link-item.h' => 'src/indicator/wifi-link-item.cpp'
1377--- src/indicator/wifi-link-item.h 2014-09-24 23:37:18 +0000
1378+++ src/indicator/wifi-link-item.cpp 2014-10-31 14:07:40 +0000
1379@@ -17,26 +17,26 @@
1380 * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
1381 */
1382
1383-#ifndef WIFI_LINK_ITEM_H
1384-#define WIFI_LINK_ITEM_H
1385+#include "wifi-link-item.h"
1386
1387-#include "menuitems/switch-item.h"
1388+#include "menuitems/text-item.h"
1389 #include "menuitems/access-point-item.h"
1390-#include "menuitems/text-item.h"
1391
1392 #include "menumodel-cpp/action-group.h"
1393 #include "menumodel-cpp/action-group-merger.h"
1394 #include "menumodel-cpp/menu.h"
1395 #include "menumodel-cpp/menu-merger.h"
1396
1397-#include <connectivity/networking/wifi/link.h>
1398 namespace networking = connectivity::networking;
1399
1400 #include <algorithm>
1401 #include <locale>
1402
1403-class WifiLinkItem : public Item
1404+class WifiLinkItem::Private : public std::enable_shared_from_this<Private>
1405 {
1406+public:
1407+ ActionGroupMerger::Ptr m_actionGroupMerger;
1408+
1409 networking::wifi::Link::Ptr m_link;
1410
1411 /// @todo do something with me...
1412@@ -66,13 +66,18 @@
1413 std::mutex m_updateActiveAccessPointMutex;
1414
1415 public:
1416- typedef std::shared_ptr<WifiLinkItem> Ptr;
1417-
1418- WifiLinkItem() = delete;
1419- virtual ~WifiLinkItem() = default;
1420- WifiLinkItem(networking::wifi::Link::Ptr link)
1421+
1422+
1423+ Private() = delete;
1424+ ~Private() {}
1425+ Private(networking::wifi::Link::Ptr link)
1426 : m_link {link}
1427+ {}
1428+
1429+ void ConstructL()
1430 {
1431+ m_actionGroupMerger = std::make_shared<ActionGroupMerger>();
1432+
1433 m_topMenu = std::make_shared<Menu>();
1434
1435 m_connectedBeforeApsMenu = std::make_shared<Menu>();
1436@@ -103,14 +108,24 @@
1437 return a_upper < b_upper;
1438 };
1439
1440+ auto that = shared_from_this();
1441+
1442 updateAccessPoints(m_link->accessPoints().get());
1443- m_link->accessPoints().changed().connect([this](std::set<networking::wifi::AccessPoint::Ptr> accessPoints){
1444- updateAccessPoints(accessPoints);
1445+ m_link->accessPoints().changed().connect([that](std::set<networking::wifi::AccessPoint::Ptr> accessPoints)
1446+ {
1447+ GMainLoopDispatch([that, accessPoints]()
1448+ {
1449+ that->updateAccessPoints(accessPoints);
1450+ });
1451 });
1452
1453 updateActiveAccessPoint(m_link->activeAccessPoint().get());
1454- m_link->activeAccessPoint().changed().connect([this](networking::wifi::AccessPoint::Ptr ap){
1455- updateActiveAccessPoint(ap);
1456+ m_link->activeAccessPoint().changed().connect([that](networking::wifi::AccessPoint::Ptr ap)
1457+ {
1458+ GMainLoopDispatch([that, ap]()
1459+ {
1460+ that->updateActiveAccessPoint(ap);
1461+ });
1462 });
1463
1464 m_otherNetwork = std::make_shared<TextItem>(_("Other network…"), "wifi", "othernetwork");
1465@@ -204,12 +219,26 @@
1466 }
1467 }
1468
1469- virtual MenuItem::Ptr
1470- menuItem() {
1471- return m_item;
1472- }
1473-
1474-
1475 };
1476
1477-#endif // WIFI_LINK_ITEM_H
1478+
1479+WifiLinkItem::WifiLinkItem(connectivity::networking::wifi::Link::Ptr link)
1480+ : d{new Private(link)}
1481+{
1482+ d->ConstructL();
1483+}
1484+
1485+WifiLinkItem::~WifiLinkItem()
1486+{}
1487+
1488+ActionGroup::Ptr
1489+WifiLinkItem::actionGroup()
1490+{
1491+ return d->m_actionGroupMerger->actionGroup();
1492+}
1493+
1494+MenuItem::Ptr
1495+WifiLinkItem::menuItem()
1496+{
1497+ return d->m_item;
1498+}
1499
1500=== added file 'src/indicator/wifi-link-item.h'
1501--- src/indicator/wifi-link-item.h 1970-01-01 00:00:00 +0000
1502+++ src/indicator/wifi-link-item.h 2014-10-31 14:07:40 +0000
1503@@ -0,0 +1,43 @@
1504+/*
1505+ * Copyright (C) 2014 Canonical, Ltd.
1506+ *
1507+ * This program is free software: you can redistribute it and/or modify it
1508+ * under the terms of the GNU General Public License version 3, as published
1509+ * by the Free Software Foundation.
1510+ *
1511+ * This program is distributed in the hope that it will be useful, but
1512+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1513+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1514+ * PURPOSE. See the GNU General Public License for more details.
1515+ *
1516+ * You should have received a copy of the GNU General Public License along
1517+ * with this program. If not, see <http://www.gnu.org/licenses/>.
1518+ *
1519+ * Authors:
1520+ * Antti Kaijanmäki <antti.kaijanmaki@canonical.com>
1521+ */
1522+
1523+#ifndef WIFI_LINK_ITEM_H
1524+#define WIFI_LINK_ITEM_H
1525+
1526+#include <connectivity/networking/wifi/link.h>
1527+
1528+#include "menuitems/item.h"
1529+
1530+class WifiLinkItem : public Item
1531+{
1532+ class Private;
1533+ std::shared_ptr<Private> d;
1534+
1535+public:
1536+ typedef std::shared_ptr<WifiLinkItem> Ptr;
1537+
1538+ WifiLinkItem() = delete;
1539+ WifiLinkItem(connectivity::networking::wifi::Link::Ptr link);
1540+ virtual ~WifiLinkItem();
1541+
1542+ virtual MenuItem::Ptr menuItem();
1543+ virtual ActionGroup::Ptr actionGroup();
1544+};
1545+
1546+#endif // WIFI_LINK_ITEM_H
1547
1548=== modified file 'src/indicator/wifi-section.cpp'
1549--- src/indicator/wifi-section.cpp 2014-09-25 18:48:39 +0000
1550+++ src/indicator/wifi-section.cpp 2014-10-31 14:07:40 +0000
1551@@ -23,7 +23,17 @@
1552
1553 #include "url-dispatcher-cpp/url-dispatcher.h"
1554
1555-class WifiSection::Private
1556+#include "menuitems/switch-item.h"
1557+#include "menuitems/text-item.h"
1558+
1559+#include "menumodel-cpp/action-group.h"
1560+#include "menumodel-cpp/action-group-merger.h"
1561+#include "menumodel-cpp/menu.h"
1562+#include "menumodel-cpp/menu-merger.h"
1563+
1564+using namespace connectivity;
1565+
1566+class WifiSection::Private : public std::enable_shared_from_this<Private>
1567 {
1568 public:
1569 std::shared_ptr<connectivity::networking::Manager> m_manager;
1570@@ -40,6 +50,10 @@
1571 Private() = delete;
1572 Private(std::shared_ptr<connectivity::networking::Manager> manager)
1573 : m_manager{manager}
1574+ {}
1575+
1576+ void
1577+ ConstructL()
1578 {
1579 m_actionGroupMerger = std::make_shared<ActionGroupMerger>();
1580 m_menu = std::make_shared<Menu>();
1581@@ -56,9 +70,14 @@
1582 m_settingsMenu->append(*m_switch);
1583 }
1584
1585+ auto that = shared_from_this();
1586+
1587 m_switch->state().set(m_manager->wifiEnabled().get());
1588- m_manager->wifiEnabled().changed().connect([this](bool value) {
1589- m_switch->state().set(value);
1590+ m_manager->wifiEnabled().changed().connect([that](bool value) {
1591+ GMainLoopDispatch([that, value]()
1592+ {
1593+ that->m_switch->state().set(value);
1594+ });
1595 });
1596 m_switch->activated().connect([this](){
1597 if (m_switch->state().get()) {
1598@@ -73,8 +92,14 @@
1599 });
1600
1601
1602- m_manager->links().changed().connect(std::bind(&Private::updateLinks, this));
1603 updateLinks();
1604+ m_manager->links().changed().connect([that](std::set<networking::Link::Ptr>)
1605+ {
1606+ GMainLoopDispatch([that]()
1607+ {
1608+ that->updateLinks();
1609+ });
1610+ });
1611
1612 m_openWifiSettings = std::make_shared<TextItem>(_("Wi-Fi settings…"), "wifi", "settings");
1613 m_openWifiSettings->activated().connect([](){
1614@@ -115,14 +140,13 @@
1615 };
1616
1617 WifiSection::WifiSection(std::shared_ptr<connectivity::networking::Manager> manager)
1618+ : d{new Private(manager)}
1619 {
1620- d.reset(new Private(manager));
1621+ d->ConstructL();
1622 }
1623
1624 WifiSection::~WifiSection()
1625-{
1626-
1627-}
1628+{}
1629
1630 ActionGroup::Ptr
1631 WifiSection::actionGroup()
1632
1633=== modified file 'src/indicator/wifi-section.h'
1634--- src/indicator/wifi-section.h 2014-08-15 11:49:44 +0000
1635+++ src/indicator/wifi-section.h 2014-10-31 14:07:40 +0000
1636@@ -27,7 +27,7 @@
1637 class WifiSection : public Section
1638 {
1639 class Private;
1640- std::unique_ptr<Private> d;
1641+ std::shared_ptr<Private> d;
1642
1643 public:
1644 typedef std::shared_ptr<WifiSection> Ptr;
1645
1646=== modified file 'src/indicator/wwan-link-item.cpp'
1647--- src/indicator/wwan-link-item.cpp 2014-10-02 11:36:00 +0000
1648+++ src/indicator/wwan-link-item.cpp 2014-10-31 14:07:40 +0000
1649@@ -23,7 +23,7 @@
1650
1651 #include "menumodel-cpp/menu.h"
1652
1653-class WwanLinkItem::Private
1654+class WwanLinkItem::Private : public std::enable_shared_from_this<Private>
1655 {
1656 public:
1657
1658@@ -39,6 +39,7 @@
1659
1660 Private() = delete;
1661 Private(Modem::Ptr modem, ModemManager::Ptr modemManager);
1662+ void ConstructL();
1663
1664 void update();
1665 void unlockSim();
1666@@ -47,6 +48,10 @@
1667 WwanLinkItem::Private::Private(Modem::Ptr modem, ModemManager::Ptr modemManager)
1668 : m_modem{modem},
1669 m_modemManager{modemManager}
1670+{}
1671+
1672+void
1673+WwanLinkItem::Private::ConstructL()
1674 {
1675 m_actionGroupMerger = std::make_shared<ActionGroupMerger>();
1676 m_menu = std::make_shared<Menu>();
1677@@ -60,6 +65,7 @@
1678 m_showIdentifier.set(false);
1679 m_showIdentifier.changed().connect(std::bind(&Private::update, this));
1680
1681+ // already synced with GMainLoop
1682 m_modem->online().changed().connect(std::bind(&Private::update, this));
1683 m_modem->simStatus().changed().connect(std::bind(&Private::update, this));
1684 m_modem->operatorName().changed().connect(std::bind(&Private::update, this));
1685@@ -152,8 +158,10 @@
1686 }
1687
1688 WwanLinkItem::WwanLinkItem(Modem::Ptr modem, ModemManager::Ptr modemManager)
1689+ : d{new Private(modem, modemManager)}
1690+
1691 {
1692- d.reset(new Private(modem, modemManager));
1693+ d->ConstructL();
1694 }
1695
1696 WwanLinkItem::~WwanLinkItem()
1697
1698=== modified file 'src/indicator/wwan-section.cpp'
1699--- src/indicator/wwan-section.cpp 2014-08-15 10:47:02 +0000
1700+++ src/indicator/wwan-section.cpp 2014-10-31 14:07:40 +0000
1701@@ -53,12 +53,17 @@
1702
1703 Private() = delete;
1704 Private(ModemManager::Ptr modemManager);
1705+ void ConstructL();
1706
1707 void modemsChanged(const std::set<Modem::Ptr> &modems);
1708 };
1709
1710 WwanSection::Private::Private(ModemManager::Ptr modemManager)
1711 : m_modemManager{modemManager}
1712+{}
1713+
1714+void
1715+WwanSection::Private::ConstructL()
1716 {
1717 m_actionGroupMerger = std::make_shared<ActionGroupMerger>();
1718 m_menuMerger = std::make_shared<MenuMerger>();
1719@@ -85,6 +90,7 @@
1720 });
1721 m_actionGroupMerger->add(*m_openCellularSettings);
1722
1723+ // already synced with GMainLoop
1724 m_modemManager->modems().changed().connect(std::bind(&Private::modemsChanged, this, std::placeholders::_1));
1725 modemsChanged(m_modemManager->modems());
1726 }
1727@@ -149,8 +155,9 @@
1728 }
1729
1730 WwanSection::WwanSection(ModemManager::Ptr modemManager)
1731+ : d{new Private(modemManager)}
1732 {
1733- d.reset(new Private(modemManager));
1734+ d->ConstructL();
1735 }
1736
1737 WwanSection::~WwanSection()
1738
1739=== modified file 'src/indicator/wwan-section.h'
1740--- src/indicator/wwan-section.h 2014-08-15 11:52:50 +0000
1741+++ src/indicator/wwan-section.h 2014-10-31 14:07:40 +0000
1742@@ -26,7 +26,7 @@
1743 class WwanSection : public Section
1744 {
1745 class Private;
1746- std::unique_ptr<Private> d;
1747+ std::shared_ptr<Private> d;
1748
1749 public:
1750 typedef std::shared_ptr<WwanSection> Ptr;
1751
1752=== modified file 'src/menumodel-cpp/gio-helpers/util.cpp'
1753--- src/menumodel-cpp/gio-helpers/util.cpp 2014-09-26 13:07:27 +0000
1754+++ src/menumodel-cpp/gio-helpers/util.cpp 2014-10-31 14:07:40 +0000
1755@@ -25,28 +25,28 @@
1756 gboolean
1757 GMainLoopDispatch::dispatch_cb(gpointer)
1758 {
1759- std::lock_guard<std::mutex> lock(_lock);
1760+ std::unique_lock<std::mutex> lock(_lock);
1761 for (auto func : _funcs) {
1762+ lock.unlock();
1763 (*func)();
1764+ lock.lock();
1765 delete func;
1766 }
1767 _funcs.clear();
1768 return G_SOURCE_REMOVE;
1769 }
1770
1771-GMainLoopDispatch::GMainLoopDispatch(std::function<void()> func)
1772+GMainLoopDispatch::GMainLoopDispatch(Func func)
1773 {
1774+ std::unique_lock<std::mutex> lock(_lock);
1775+
1776 if (g_main_context_acquire(g_main_context_default())) {
1777- if (_funcs.empty())
1778- func();
1779- else {
1780- std::function<void()> *funcPtr = new std::function<void()>(func);
1781- _funcs.push_back(funcPtr);
1782- }
1783+ // already running inside GMainLoop..
1784+ // free the lock and dispatch immediately.
1785+ lock.unlock();
1786+ func();
1787 g_main_context_release(g_main_context_default());
1788 } else {
1789- std::lock_guard<std::mutex> lock(_lock);
1790-
1791 std::function<void()> *funcPtr = new std::function<void()>(func);
1792 if (_funcs.empty()) {
1793 g_idle_add_full(G_PRIORITY_HIGH,
1794
1795=== modified file 'src/menumodel-cpp/gio-helpers/util.h'
1796--- src/menumodel-cpp/gio-helpers/util.h 2014-09-26 13:07:27 +0000
1797+++ src/menumodel-cpp/gio-helpers/util.h 2014-10-31 14:07:40 +0000
1798@@ -54,7 +54,7 @@
1799 g_main_context_release(g_main_context_default());
1800 } else {
1801 std::unique_lock<std::mutex> lk(m_mutex);
1802- g_idle_add_full(G_PRIORITY_HIGH,
1803+ g_idle_add_full(G_PRIORITY_HIGH + 1,
1804 GSourceFunc(GMainLoopSync::dispatch_cb),
1805 this,
1806 nullptr);
1807@@ -77,7 +77,7 @@
1808 static std::list<Func *> _funcs;
1809
1810 //GMainLoopDispatch() = delete;
1811- GMainLoopDispatch(std::function<void()> func);
1812+ GMainLoopDispatch(Func func);
1813 };
1814
1815 struct GObjectDeleter {
1816
1817=== modified file 'tests/unit/indicator/menuitems/CMakeLists.txt'
1818--- tests/unit/indicator/menuitems/CMakeLists.txt 2014-08-19 21:03:04 +0000
1819+++ tests/unit/indicator/menuitems/CMakeLists.txt 2014-10-31 14:07:40 +0000
1820@@ -2,6 +2,7 @@
1821 set(
1822 MENUITEMS_CPP_UNIT_TESTS_SRC
1823 test-access-point-item.cpp
1824+ ${CMAKE_SOURCE_DIR}/src/indicator/menuitems/access-point-item.cpp
1825 test-switch-item.cpp
1826 )
1827
1828
1829=== modified file 'tests/unit/indicator/menuitems/test-access-point-item.cpp'
1830--- tests/unit/indicator/menuitems/test-access-point-item.cpp 2014-05-12 11:48:42 +0000
1831+++ tests/unit/indicator/menuitems/test-access-point-item.cpp 2014-10-31 14:07:40 +0000
1832@@ -30,6 +30,8 @@
1833 using namespace QtDBusTest;
1834 using namespace testutils;
1835
1836+using namespace connectivity;
1837+
1838 namespace
1839 {
1840

Subscribers

People subscribed via source and target branches