Merge lp:~thomas-voss/location-service/wait-for-service into lp:location-service

Proposed by Thomas Voß
Status: Merged
Approved by: Thomas Voß
Approved revision: 292
Merged at revision: 292
Proposed branch: lp:~thomas-voss/location-service/wait-for-service
Merge into: lp:location-service
Diff against target: 318 lines (+96/-46)
3 files modified
src/location/dbus/stub/service.cpp (+75/-39)
src/location/dbus/stub/service.h (+17/-7)
src/location/providers/remote/provider.h (+4/-0)
To merge this branch: bzr merge lp:~thomas-voss/location-service/wait-for-service
Reviewer Review Type Date Requested Status
Simon Fels (community) Approve
Thomas Voß Pending
Review via email: mp+319402@code.launchpad.net

Commit message

Postpone creation of dbus stubs until service becomes available.

This is the first step in making the overall setup of out-of-process providers
and clients more resilient against the service going away or starting after a provider
has been started.

Description of the change

Postpone creation of dbus stubs until service becomes available.

This is the first step in making the overall setup of out-of-process providers
and clients more resilient against the service going away or starting after a provider
has been started.

To post a comment you must log in.
Revision history for this message
Simon Fels (morphis) wrote :

LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/location/dbus/stub/service.cpp'
2--- src/location/dbus/stub/service.cpp 2017-03-07 10:01:34 +0000
3+++ src/location/dbus/stub/service.cpp 2017-03-09 09:16:13 +0000
4@@ -45,52 +45,64 @@
5 g_bus_get(static_cast<GBusType>(bus), nullptr, on_bus_acquired, new BusAcquisitionContext{std::move(callback)});
6 }
7
8-location::dbus::stub::Service::Service(const glib::SharedObject<GDBusConnection>& connection,
9- const glib::SharedObject<ComUbuntuLocationService>& proxy)
10- : connection{connection},
11- proxy{proxy},
12- state_{boost::lexical_cast<Service::State>(com_ubuntu_location_service_get_state(proxy.get()))},
13- does_satellite_based_positioning_{com_ubuntu_location_service_get_does_satellite_based_positioning(proxy.get())},
14- does_report_cell_and_wifi_ids_{com_ubuntu_location_service_get_does_report_cell_and_wifi_ids(proxy.get())},
15- is_online_{com_ubuntu_location_service_get_is_online(proxy.get())}
16-{
17-}
18-
19-std::shared_ptr<location::dbus::stub::Service> location::dbus::stub::Service::finalize_construction()
20+location::dbus::stub::Service::Service()
21+{
22+}
23+
24+void location::dbus::stub::Service::deinit()
25+{
26+ for (auto id : signal_handler_ids)
27+ g_signal_handler_disconnect(proxy_.get(), id);
28+
29+ signal_handler_ids.clear();
30+}
31+
32+std::shared_ptr<location::dbus::stub::Service> location::dbus::stub::Service::init(
33+ const glib::SharedObject<GDBusConnection>& connection, const glib::SharedObject<ComUbuntuLocationService>& service)
34 {
35 auto sp = shared_from_this();
36 std::weak_ptr<Service> wp{sp};
37
38+ deinit();
39+
40+ connection_ = connection;
41+ proxy_ = service;
42+
43+ state_ = boost::lexical_cast<Service::State>(com_ubuntu_location_service_get_state(proxy_.get()));
44+ does_satellite_based_positioning_ = com_ubuntu_location_service_get_does_satellite_based_positioning(proxy_.get());
45+ does_report_cell_and_wifi_ids_ = com_ubuntu_location_service_get_does_report_cell_and_wifi_ids(proxy_.get());
46+ is_online_ = com_ubuntu_location_service_get_is_online(proxy_.get());
47+
48 does_satellite_based_positioning_.changed().connect([this, wp](bool value)
49 {
50 if (auto sp = wp.lock())
51- com_ubuntu_location_service_set_does_satellite_based_positioning(Service::proxy.get(), value);
52+ com_ubuntu_location_service_set_does_satellite_based_positioning(proxy_.get(), value);
53 });
54
55 does_report_cell_and_wifi_ids_.changed().connect([this, wp](bool value)
56 {
57 if (auto sp = wp.lock())
58- com_ubuntu_location_service_set_does_report_cell_and_wifi_ids(Service::proxy.get(), value);
59+ com_ubuntu_location_service_set_does_report_cell_and_wifi_ids(proxy_.get(), value);
60 });
61
62 is_online_.changed().connect([this, wp](bool value)
63 {
64 if (auto sp = wp.lock())
65- com_ubuntu_location_service_set_is_online(Service::proxy.get(), value);
66+ com_ubuntu_location_service_set_is_online(proxy_.get(), value);
67 });
68
69 signal_handler_ids.insert(
70- g_signal_connect_data(Service::proxy.get(), "notify::does-satellite-based-positioning",
71+ g_signal_connect_data(proxy_.get(), "notify::does-satellite-based-positioning",
72 G_CALLBACK(on_does_satellite_based_positioning_changed),
73 new Holder{wp}, Holder::closure_notify, GConnectFlags(0)));
74
75 signal_handler_ids.insert(
76- g_signal_connect_data(Service::proxy.get(), "notify::does-report-cell-and-wifi-ids",
77+ g_signal_connect_data(proxy_.get(), "notify::does-report-cell-and-wifi-ids",
78 G_CALLBACK(on_does_report_cell_and_wifi_ids_changed),
79 new Holder{wp}, Holder::closure_notify, GConnectFlags(0)));
80
81 signal_handler_ids.insert(
82- g_signal_connect_data(Service::proxy.get(), "notify::is-online",
83+ g_signal_connect_data(proxy_.get(), "notify::is-online",
84 G_CALLBACK(on_is_online_changed),
85 new Holder{wp}, Holder::closure_notify, GConnectFlags(0)));
86
87@@ -99,8 +111,7 @@
88
89 location::dbus::stub::Service::~Service()
90 {
91- for (auto id : signal_handler_ids)
92- g_signal_handler_disconnect(proxy.get(), id);
93+ deinit();
94 }
95
96 void location::dbus::stub::Service::create_session_for_criteria(const Criteria& criteria, const std::function<void(const Session::Ptr&)>& cb)
97@@ -109,7 +120,7 @@
98 std::weak_ptr<Service> wp{sp};
99
100 com_ubuntu_location_service_call_create_session_for_criteria(
101- proxy.get(), dbus::encode(criteria), nullptr, on_session_ready, new Service::SessionCreationContext{std::move(cb), wp});
102+ proxy_.get(), dbus::encode(criteria), nullptr, on_session_ready, new Service::SessionCreationContext{std::move(cb), wp});
103 }
104
105 void location::dbus::stub::Service::add_provider(const Provider::Ptr& provider)
106@@ -118,10 +129,10 @@
107 std::weak_ptr<Service> wp{sp};
108
109 auto path = "/providers/" + std::to_string(provider_counter++);
110- auto skeleton = location::providers::remote::Provider::Skeleton::create(connection, path, provider);
111+ auto skeleton = location::providers::remote::Provider::Skeleton::create(connection_, path, provider);
112
113 com_ubuntu_location_service_call_add_provider(
114- proxy.get(), path.c_str(), nullptr, Service::on_provider_added, new Service::ProviderAdditionContext{skeleton, wp});
115+ proxy_.get(), path.c_str(), nullptr, Service::on_provider_added, new Service::ProviderAdditionContext{skeleton, wp});
116 }
117
118 const core::Property<location::Service::State>& location::dbus::stub::Service::state() const
119@@ -152,7 +163,6 @@
120 void location::dbus::stub::Service::on_proxy_ready(GObject* source, GAsyncResult* res, gpointer user_data)
121 {
122 LOCATION_DBUS_TRACE_STATIC_TRAMPOLIN;
123-
124 boost::ignore_unused(source);
125
126 if (auto context = static_cast<Service::ProxyCreationContext*>(user_data))
127@@ -166,10 +176,9 @@
128 }
129 else
130 {
131- location::dbus::stub::Service::Ptr sp{
132- new location::dbus::stub::Service{
133- context->connection, location::glib::make_shared_object(stub)}};
134- context->cb(make_result(sp->finalize_construction()));
135+ context->cb(make_result(
136+ context->instance->init(
137+ context->connection, location::glib::make_shared_object(stub))));
138 }
139
140 delete context;
141@@ -179,7 +188,6 @@
142 void location::dbus::stub::Service::on_bus_acquired(GObject* source, GAsyncResult* res, gpointer user_data)
143 {
144 LOCATION_DBUS_TRACE_STATIC_TRAMPOLIN;
145-
146 boost::ignore_unused(source);
147
148 if (auto context = static_cast<Service::BusAcquisitionContext*>(user_data))
149@@ -193,19 +201,47 @@
150 }
151 else
152 {
153- com_ubuntu_location_service_proxy_new(
154- bus, G_DBUS_PROXY_FLAGS_NONE, location::dbus::Service::name(), location::dbus::Service::path(),
155- nullptr, on_proxy_ready, new Service::ProxyCreationContext{location::glib::make_shared_object(bus), context->cb});
156+ auto name_appeared_for_creation_context =
157+ new NameAppearedForCreationContext{0, std::move(context->cb)};
158+
159+ name_appeared_for_creation_context->watch_id =
160+ g_bus_watch_name_on_connection(
161+ bus, location::dbus::Service::name(), G_BUS_NAME_WATCHER_FLAGS_NONE,
162+ on_name_appeared_for_creation, nullptr,
163+ name_appeared_for_creation_context, nullptr);
164 }
165
166 delete context;
167 }
168 }
169
170+void location::dbus::stub::Service::on_name_appeared_for_creation(
171+ GDBusConnection* bus, const gchar* name, const gchar* name_owner, gpointer user_data)
172+{
173+ LOCATION_DBUS_TRACE_STATIC_TRAMPOLIN;
174+ boost::ignore_unused(name, name_owner);
175+
176+ if (auto context = static_cast<NameAppearedForCreationContext*>(user_data))
177+ {
178+ com_ubuntu_location_service_proxy_new(
179+ bus, G_DBUS_PROXY_FLAGS_NONE, location::dbus::Service::name(), location::dbus::Service::path(),
180+ nullptr, on_proxy_ready, new Service::ProxyCreationContext
181+ {
182+ location::glib::make_shared_object(bus),
183+ Ptr{new Service{}},
184+ context->cb
185+ });
186+
187+ // Make sure that we only react to name appeared events once in this code path.
188+ g_bus_unwatch_name(context->watch_id);
189+ // Clean up our context.
190+ delete context;
191+ }
192+}
193+
194 void location::dbus::stub::Service::on_provider_added(GObject *source, GAsyncResult *res, gpointer user_data)
195 {
196 LOCATION_DBUS_TRACE_STATIC_TRAMPOLIN;
197-
198 boost::ignore_unused(source);
199
200 if (auto context = static_cast<Service::ProviderAdditionContext*>(user_data))
201@@ -214,7 +250,7 @@
202 {
203 GError* error{nullptr};
204 if (com_ubuntu_location_service_call_add_provider_finish(
205- sp->proxy.get(), res, &error))
206+ sp->proxy_.get(), res, &error))
207 {
208 sp->providers.insert(context->provider);
209 }
210@@ -239,12 +275,12 @@
211 {
212 GError* error{nullptr}; char* path{nullptr};
213 com_ubuntu_location_service_call_create_session_for_criteria_finish(
214- sp->proxy.get(), &path, res, &error);
215+ sp->proxy_.get(), &path, res, &error);
216
217 if (!error)
218 {
219 auto cb = context->cb;
220- stub::Session::create(sp->connection, path, [cb](const Result<stub::Session::Ptr>& result)
221+ stub::Session::create(sp->connection_, path, [cb](const Result<stub::Session::Ptr>& result)
222 {
223 if (result)
224 cb(result.value());
225@@ -271,7 +307,7 @@
226 {
227 sp->does_satellite_based_positioning() =
228 com_ubuntu_location_service_get_does_satellite_based_positioning(
229- sp->proxy.get());
230+ sp->proxy_.get());
231 }
232 }
233 }
234@@ -287,7 +323,7 @@
235 {
236 sp->does_report_cell_and_wifi_ids() =
237 com_ubuntu_location_service_get_does_report_cell_and_wifi_ids(
238- sp->proxy.get());
239+ sp->proxy_.get());
240 }
241 }
242 }
243@@ -303,7 +339,7 @@
244 {
245 sp->is_online() =
246 com_ubuntu_location_service_get_is_online(
247- sp->proxy.get());
248+ sp->proxy_.get());
249 }
250 }
251 }
252
253=== modified file 'src/location/dbus/stub/service.h'
254--- src/location/dbus/stub/service.h 2017-03-07 10:01:34 +0000
255+++ src/location/dbus/stub/service.h 2017-03-09 09:16:13 +0000
256@@ -59,9 +59,18 @@
257 };
258 static void on_bus_acquired(GObject* source, GAsyncResult* res, gpointer user_data);
259
260+ struct NameAppearedForCreationContext
261+ {
262+ guint watch_id;
263+ std::function<void(const Result<Service::Ptr>&)> cb;
264+ };
265+ static void on_name_appeared_for_creation(
266+ GDBusConnection* connection_, const gchar* name, const gchar* name_owner, gpointer user_data);
267+
268 struct ProxyCreationContext
269 {
270 glib::SharedObject<GDBusConnection> connection;
271+ Service::Ptr instance;
272 std::function<void(const Result<Service::Ptr>&)> cb;
273 };
274 static void on_proxy_ready(GObject* source, GAsyncResult* res, gpointer user_data);
275@@ -84,13 +93,14 @@
276 static void on_does_report_cell_and_wifi_ids_changed(GObject* object, GParamSpec* spec, gpointer user_data);
277 static void on_is_online_changed(GObject* object, GParamSpec* spec, gpointer user_data);
278
279- Service(const glib::SharedObject<GDBusConnection>& connection,
280- const glib::SharedObject<ComUbuntuLocationService>& service);
281-
282- std::shared_ptr<Service> finalize_construction();
283-
284- glib::SharedObject<GDBusConnection> connection;
285- glib::SharedObject<ComUbuntuLocationService> proxy;
286+ Service();
287+
288+ void deinit();
289+ std::shared_ptr<Service> init(const glib::SharedObject<GDBusConnection>& connection_,
290+ const glib::SharedObject<ComUbuntuLocationService>& service);
291+
292+ glib::SharedObject<GDBusConnection> connection_;
293+ glib::SharedObject<ComUbuntuLocationService> proxy_;
294 std::set<ulong> signal_handler_ids;
295
296 std::uint64_t provider_counter{0};
297
298=== modified file 'src/location/providers/remote/provider.h'
299--- src/location/providers/remote/provider.h 2017-03-04 21:43:23 +0000
300+++ src/location/providers/remote/provider.h 2017-03-09 09:16:13 +0000
301@@ -43,6 +43,8 @@
302 class Stub : public location::Provider, public std::enable_shared_from_this<Stub>
303 {
304 public:
305+ using Ptr = std::shared_ptr<Stub>;
306+
307 // Asynchronously tries to create a new Stub instance, setting up proxy access to the remote
308 // end. Reports errors via 'cb'.
309 static void create(const glib::SharedObject<GDBusConnection>& connection,
310@@ -91,6 +93,8 @@
311 class Skeleton : public location::Provider, public std::enable_shared_from_this<Skeleton>
312 {
313 public:
314+ using Ptr = std::shared_ptr<Skeleton>;
315+
316 // Asynchronously tries to create a new Skeleton instance, setting up
317 // proxy access to the remote end. Reports errors via cb.
318 static Provider::Ptr create(

Subscribers

People subscribed via source and target branches

to all changes: