Merge lp:~thomas-voss/location-service/robustify-event-propagation-in-case-of-multiple-providers-running into lp:location-service/15.04

Proposed by Thomas Voß
Status: Needs review
Proposed branch: lp:~thomas-voss/location-service/robustify-event-propagation-in-case-of-multiple-providers-running
Merge into: lp:location-service/15.04
Diff against target: 671 lines (+513/-51)
5 files modified
src/location_service/com/ubuntu/location/CMakeLists.txt (+1/-0)
src/location_service/com/ubuntu/location/dispatching_provider.cpp (+325/-0)
src/location_service/com/ubuntu/location/dispatching_provider.h (+90/-0)
src/location_service/com/ubuntu/location/service/daemon.cpp (+91/-41)
tests/acceptance_tests.cpp (+6/-10)
To merge this branch: bzr merge lp:~thomas-voss/location-service/robustify-event-propagation-in-case-of-multiple-providers-running
Reviewer Review Type Date Requested Status
Alberto Mardegan (community) Approve
Loïc Minier Pending
PS Jenkins bot continuous-integration Pending
Review via email: mp+277789@code.launchpad.net

This proposal supersedes a proposal from 2014-10-16.

Commit message

Introduce a dispatching provider that leverages a functor to hand over updates and invocations to/from providers.
Adjust acceptance tests to account for multiple providers.

Description of the change

Introduce a dispatching provider that leverages a functor to hand over updates and invocations to/from providers.
Adjust acceptance tests to account for multiple providers.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Loïc Minier (lool) wrote : Posted in a previous version of this proposal

LGTM

review: Approve
131. By Thomas Voß

[ Alberto Mardegan ]
* Make sure that injected time is given in milliseconds
[ Thomas Voß ]
* Cherry-pick rev. 196 and 199 from lp:location-service. The changes
  got accidentally removed by merging the outstanding documentation
  branch.
* Handle responses of clients to updates asynchronously. Rely on
  dummy::ConnectivityManager as harvesting is disabled anyway. (LP:
  #1462664, #1387643)
[ Thomas Voß ]
* Add documentation for debugging, hacking and debugging the location
  service. Pull manual testing instructions over from the wiki. Add
  tools for formatting the source.
[ thomas-voss ]
* Add documentation for debugging, hacking and debugging the location
  service. Pull manual testing instructions over from the wiki. Add
  tools for formatting the source.
[ CI Train Bot ]
* New rebuild forced.
[ Manuel de la Pena ]
* Make sure that cached modems are considered as well when calculating
  connection characteristics.
[ CI Train Bot ]
* New rebuild forced.
[ Manuel de la Pena ]
* Improve the selection of the bag of providers to ensure that the
  locations used are within a reasonable time margin.
* Remove the pimpl implementation from the providers and hide their
  public headers because they should only be used within the project.
[ Thomas Voß ]
* Increase default timeout for downloading gps xtra data. (LP:
  #1447161)
[ CI Train Bot ]
* New rebuild forced.
[ Manuel de la Pena ]
* If an exception is thrown from the io_executor run method it must be
  caught, logger and continued with the main loop.
[ CI Train Bot ]
* Launchpad automatic translations update. added: po/af.po po/bg.po
  po/sk.po
* New rebuild forced.
[ thomas-voss ]
* Account for dbus interface breakage in NM from 0.9.8.8 -> 0.9.10.0.
[ thomas-voss ]
* Automatically clean up session store for dead clients. (LP:
  #1418033)
[ thomas-voss ]
* Make the remote::Provider::Stub fail loudly on construction if the
  other side is not reachable. Relax the exception in
  location::Daemon::main and do not exit if instantiating a provider
  fails. (LP: #1414591)
[ CI Train Bot ]
* Resync trunk
[ thomas-voss ]
* Add an interface for querying settings by key. Add an implementation
  leveraging boost::property_tree to provide settings. (LP: #1362765)
* Allow for enabling/disabling providers. Wire up engine state changes
  to enabling/disabling of providers. (LP: #1392399)
[ thomas-voss ]
* Print details about visible space vehicles to the gps provider test
  case. (LP: #1408984)
[ thomas-voss ]
* Fix #1394204 by: (LP: #1394204)
[ Ubuntu daily release ]
* New rebuild forced
[ thomas-voss ]
* Make sure that devices being added/removed by NetworkManager are
  handled correctly. (LP: #1390490)
[ CI bot ]
* Resync trunk
[ Kevin DuBois ]
* The headers shipped in libubuntu-location-service-dev contain
  includes that are provided in the libboost-dev package (specifically
  headers like boost/units/cmath.hpp). Make the dev package depend on
  libboost-dev so the downstreams get what they need to compile
  against the libubuntu-location-service-dev headers
* New rebuild forced
[ thomas-voss ]
* Bump build dependency.
* Disconnect event connections for bag of providers. (LP: #1387572)
[ thomas-voss ]
* Prevent multiple invocations of start positioning on android GPS HAL
  to prevent buggy HAL implementations from blocking. Allow for
  decorated provider names to enable moving providers OOP. (LP:
  #1382501)

132. By Thomas Voß

Revert accidental change to debian/source/format.

Revision history for this message
Alberto Mardegan (mardy) wrote :

The code looks good to me, but I feel that this makes the logic even more complicated.

I would much rather force all providers to be out of process. This would lead to a simpler design, and might also make it possible to free some memory when the GPS is not in use.

I'm approving this because code-wise it's fine, but if it were for me, I would not merge it.

review: Approve
133. By Thomas Voß

Explicitly stop bus instances on shut down.

Revision history for this message
Michał Karnicki (karni) wrote :

Was browsing this out of curiosity and to learn. Tiny comment - the license headers should probably contain 2015?

Unmerged revisions

133. By Thomas Voß

Explicitly stop bus instances on shut down.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt'
--- src/location_service/com/ubuntu/location/CMakeLists.txt 2015-04-23 14:48:44 +0000
+++ src/location_service/com/ubuntu/location/CMakeLists.txt 2015-11-25 08:29:55 +0000
@@ -19,6 +19,7 @@
19 non_selecting_provider_selection_policy.cpp19 non_selecting_provider_selection_policy.cpp
2020
21 criteria.cpp21 criteria.cpp
22 dispatching_provider.cpp
22 engine.cpp23 engine.cpp
23 init_and_shutdown.cpp24 init_and_shutdown.cpp
24 position.cpp25 position.cpp
2526
=== added file 'src/location_service/com/ubuntu/location/dispatching_provider.cpp'
--- src/location_service/com/ubuntu/location/dispatching_provider.cpp 1970-01-01 00:00:00 +0000
+++ src/location_service/com/ubuntu/location/dispatching_provider.cpp 2015-11-25 08:29:55 +0000
@@ -0,0 +1,325 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18
19#include <com/ubuntu/location/dispatching_provider.h>
20
21#include <com/ubuntu/location/logging.h>
22
23#include <future>
24
25namespace location = com::ubuntu::location;
26
27location::DispatchingProvider::Ptr location::DispatchingProvider::create(
28 const location::DispatchingProvider::Dispatcher& dispatcher,
29 const location::Provider::Ptr& fwd)
30{
31 std::shared_ptr<location::DispatchingProvider> sp
32 {
33 new location::DispatchingProvider{dispatcher, fwd}
34 };
35 return sp->init();
36}
37
38location::DispatchingProvider::DispatchingProvider(const location::DispatchingProvider::Dispatcher& dispatcher, const location::Provider::Ptr& fwd)
39 : dispatcher{dispatcher},
40 fwd{fwd}
41{
42 if (not dispatcher) throw std::logic_error
43 {
44 "com::ubuntu::location::DispatchingProvider: Cannot operate without valid dispatcher"
45 };
46
47 if (not fwd) throw std::logic_error
48 {
49 "com::ubuntu::location::DispatchingProvider: Cannot operate without valid Provider"
50 };
51}
52
53location::DispatchingProvider::~DispatchingProvider()
54{
55}
56
57bool location::DispatchingProvider::supports(const location::Provider::Features& f) const
58{
59 std::promise<bool> promise;
60 std::future<bool> future = promise.get_future();
61
62 dispatcher([&]()
63 {
64 try
65 {
66 promise.set_value(fwd->supports(f));
67 } catch(const std::exception& e)
68 {
69 LOG(WARNING) << e.what();
70 promise.set_exception(std::current_exception());
71 } catch(...)
72 {
73 promise.set_exception(std::current_exception());
74 }
75 });
76
77 return future.get();
78}
79
80bool location::DispatchingProvider::requires(const location::Provider::Requirements& r) const
81{
82 std::promise<bool> promise;
83 std::future<bool> future = promise.get_future();
84
85 dispatcher([&]()
86 {
87 try
88 {
89 promise.set_value(fwd->requires(r));
90 } catch(const std::exception& e)
91 {
92 LOG(WARNING) << e.what();
93 promise.set_exception(std::current_exception());
94 } catch(...)
95 {
96 promise.set_exception(std::current_exception());
97 }
98 });
99
100 return future.get();
101}
102
103bool location::DispatchingProvider::matches_criteria(const location::Criteria& criteria)
104{
105 std::promise<bool> promise;
106 std::future<bool> future = promise.get_future();
107
108 dispatcher([&]()
109 {
110 try
111 {
112 promise.set_value(fwd->matches_criteria(criteria));
113 } catch(const std::exception& e)
114 {
115 LOG(WARNING) << e.what();
116 promise.set_exception(std::current_exception());
117 } catch(...)
118 {
119 promise.set_exception(std::current_exception());
120 }
121 });
122
123 return future.get();
124}
125
126// We forward all events to the other providers.
127void location::DispatchingProvider::on_wifi_and_cell_reporting_state_changed(location::WifiAndCellIdReportingState state)
128{
129 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
130 dispatcher([wp, state]()
131 {
132 auto sp = wp.lock();
133
134 if (not sp)
135 return;
136
137 sp->fwd->on_wifi_and_cell_reporting_state_changed(state);
138 });
139}
140
141void location::DispatchingProvider::on_reference_location_updated(const location::Update<location::Position>& position)
142{
143 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
144 dispatcher([wp, position]()
145 {
146 auto sp = wp.lock();
147
148 if (not sp)
149 return;
150
151 sp->fwd->on_reference_location_updated(position);
152 });
153}
154
155void location::DispatchingProvider::on_reference_velocity_updated(const location::Update<location::Velocity>& velocity)
156{
157 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
158 dispatcher([wp, velocity]()
159 {
160 auto sp = wp.lock();
161
162 if (not sp)
163 return;
164
165 sp->fwd->on_reference_velocity_updated(velocity);
166 });
167}
168
169void location::DispatchingProvider::on_reference_heading_updated(const location::Update<location::Heading>& heading)
170{
171 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
172 dispatcher([wp, heading]()
173 {
174 auto sp = wp.lock();
175
176 if (not sp)
177 sp->fwd->on_reference_heading_updated(heading);
178 });
179}
180
181// As well as the respective state change requests.
182void location::DispatchingProvider::start_position_updates()
183{
184 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
185 dispatcher([wp]()
186 {
187 auto sp = wp.lock();
188
189 if (not sp)
190 return;
191
192 sp->fwd->state_controller()->start_position_updates();
193 });
194}
195
196void location::DispatchingProvider::stop_position_updates()
197{
198 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
199 dispatcher([wp]()
200 {
201 auto sp = wp.lock();
202
203 if (not sp)
204 return;
205
206 sp->fwd->state_controller()->stop_position_updates();
207 });
208}
209
210void location::DispatchingProvider::start_heading_updates()
211{
212 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
213 dispatcher([wp]()
214 {
215 auto sp = wp.lock();
216
217 if (not sp)
218 return;
219
220 sp->fwd->state_controller()->start_heading_updates();
221 });
222}
223
224void location::DispatchingProvider::stop_heading_updates()
225{
226 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
227 dispatcher([wp]()
228 {
229 auto sp = wp.lock();
230
231 if (not sp)
232 return;
233
234 sp->fwd->state_controller()->stop_heading_updates();
235 });
236}
237
238void location::DispatchingProvider::start_velocity_updates()
239{
240 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
241 dispatcher([wp]()
242 {
243 auto sp = wp.lock();
244
245 if (not sp)
246 return;
247
248 sp->fwd->state_controller()->start_velocity_updates();
249 });
250}
251
252void location::DispatchingProvider::stop_velocity_updates()
253{
254 std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
255 dispatcher([wp]()
256 {
257 auto sp = wp.lock();
258
259 if (not sp)
260 return;
261
262 sp->fwd->state_controller()->stop_velocity_updates();
263 });
264}
265
266location::DispatchingProvider::Ptr location::DispatchingProvider::init()
267{
268 auto sp = shared_from_this();
269 std::weak_ptr<location::DispatchingProvider> wp{sp};
270 connections.push_back(fwd->updates().position.connect([wp](const location::Update<location::Position>& update)
271 {
272 auto sp = wp.lock();
273
274 if (not sp)
275 return;
276
277 sp->dispatcher([wp, update]()
278 {
279 auto sp = wp.lock();
280
281 if (not sp)
282 return;
283
284 sp->mutable_updates().position(update);
285 });
286 }));
287
288 connections.push_back(fwd->updates().heading.connect([wp](const location::Update<location::Heading>& update)
289 {
290 auto sp = wp.lock();
291
292 if (not sp)
293 return;
294
295 sp->dispatcher([wp, update]()
296 {
297 auto sp = wp.lock();
298
299 if (not sp)
300 return;
301
302 sp->mutable_updates().heading(update);
303 });
304 }));
305
306 connections.push_back(fwd->updates().velocity.connect([wp](const location::Update<location::Velocity>& update)
307 {
308 auto sp = wp.lock();
309
310 if (not sp)
311 return;
312
313 sp->dispatcher([wp, update]()
314 {
315 auto sp = wp.lock();
316
317 if (not sp)
318 return;
319
320 sp->mutable_updates().velocity(update);
321 });
322 }));
323
324 return sp;
325}
0326
=== added file 'src/location_service/com/ubuntu/location/dispatching_provider.h'
--- src/location_service/com/ubuntu/location/dispatching_provider.h 1970-01-01 00:00:00 +0000
+++ src/location_service/com/ubuntu/location/dispatching_provider.h 2015-11-25 08:29:55 +0000
@@ -0,0 +1,90 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Thomas Voß <thomas.voss@canonical.com>
17 */
18
19#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_DISPATCHING_PROVIDER_H_
20#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_DISPATCHING_PROVIDER_H_
21
22#include <com/ubuntu/location/provider.h>
23
24#include <functional>
25#include <memory>
26
27namespace com
28{
29namespace ubuntu
30{
31namespace location
32{
33// A Provider implementation that wraps another provider implementation
34// dispatching events/invocations via a Dispatcher functor. The dispatcher
35// can either immediately process the given task or hand it over to a runtime
36// with an associated event loop.
37class DispatchingProvider : public Provider, public std::enable_shared_from_this<DispatchingProvider>
38{
39public:
40 // To safe us some typing.
41 typedef std::shared_ptr<DispatchingProvider> Ptr;
42
43 // The Dispatcher functor that is invoked for all incoming
44 // invocations and for all events, with both of them being
45 // wrapped as a task.
46 typedef std::function<void()> Task;
47 typedef std::function<void(Task)> Dispatcher;
48
49 // Create a new instance wired up to the given Provider instance.
50 static DispatchingProvider::Ptr create(const Dispatcher& dispatcher, const Provider::Ptr& fwd);
51
52 ~DispatchingProvider() noexcept;
53
54 bool supports(const location::Provider::Features& f) const override;
55 bool requires(const location::Provider::Requirements& r) const override;
56 bool matches_criteria(const location::Criteria&) override;
57
58 // We forward all events to the other providers.
59 void on_wifi_and_cell_reporting_state_changed(WifiAndCellIdReportingState state) override;
60 void on_reference_location_updated(const location::Update<location::Position>& position) override;
61 void on_reference_velocity_updated(const location::Update<location::Velocity>& velocity) override;
62 void on_reference_heading_updated(const location::Update<location::Heading>& heading) override;
63
64 // As well as the respective state change requests.
65 void start_position_updates() override;
66 void stop_position_updates() override;
67 void start_heading_updates() override;
68 void stop_heading_updates() override;
69 void start_velocity_updates() override;
70 void stop_velocity_updates() override;
71
72private:
73 // We want to pass ourselves around.
74 DispatchingProvider(const Dispatcher& dispatcher, const Provider::Ptr& fwd);
75
76 // Two stage initialization is evil, but we are somewhat forced to do it.
77 DispatchingProvider::Ptr init();
78
79 // The dispatcher we rely on to dispatch events/invocations.
80 Dispatcher dispatcher;
81 // The provider that we relay to/from.
82 Provider::Ptr fwd;
83 // We store all connections that should be cut on destruction.
84 std::vector<core::ScopedConnection> connections;
85};
86}
87}
88}
89
90#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_DISPATCHING_PROVIDER_H_
091
=== modified file 'src/location_service/com/ubuntu/location/service/daemon.cpp'
--- src/location_service/com/ubuntu/location/service/daemon.cpp 2015-10-23 13:43:32 +0000
+++ src/location_service/com/ubuntu/location/service/daemon.cpp 2015-11-25 08:29:55 +0000
@@ -20,6 +20,8 @@
20#include <com/ubuntu/location/boost_ptree_settings.h>20#include <com/ubuntu/location/boost_ptree_settings.h>
21#include <com/ubuntu/location/provider_factory.h>21#include <com/ubuntu/location/provider_factory.h>
2222
23#include <com/ubuntu/location/logging.h>
24#include <com/ubuntu/location/dispatching_provider.h>
23#include <com/ubuntu/location/connectivity/dummy_connectivity_manager.h>25#include <com/ubuntu/location/connectivity/dummy_connectivity_manager.h>
2426
25#include <com/ubuntu/location/service/default_configuration.h>27#include <com/ubuntu/location/service/default_configuration.h>
@@ -39,6 +41,8 @@
3941
40#include <core/posix/signal.h>42#include <core/posix/signal.h>
4143
44#include <boost/asio.hpp>
45
42#include <system_error>46#include <system_error>
43#include <thread>47#include <thread>
4448
@@ -74,6 +78,88 @@
74 }78 }
75};79};
7680
81// We bundle our "global" runtime dependencies here, specifically
82// a dispatcher to decouple multiple in-process providers from one
83// another , forcing execution to a well known set of threads.
84struct Runtime
85{
86 // Our default concurrency setup.
87 static constexpr const std::uint32_t worker_threads = 2;
88
89 // Our global singleton instance.
90 static Runtime& instance()
91 {
92 static Runtime runtime;
93 return runtime;
94 }
95
96 Runtime()
97 : running{true},
98 service{worker_threads},
99 strand{service},
100 keep_alive{service}
101 {
102 for (unsigned int i = 0; i < worker_threads; i++)
103 workers.push_back(std::thread
104 {
105 [this]()
106 {
107 while(running)
108 {
109 try
110 {
111 service.run();
112 break;
113 }
114 catch (const std::exception& e)
115 {
116 LOG(WARNING) << e.what();
117 }
118 catch (...)
119 {
120 LOG(WARNING) << "Unknown exception caught while executing boost::asio::io_service";
121 }
122 }
123 }
124 });
125 }
126
127 ~Runtime()
128 {
129 stop();
130 }
131
132 void stop()
133 {
134 VLOG(1) << __PRETTY_FUNCTION__;
135 running = false;
136 service.stop();
137 VLOG(1) << "\t Service stopped.";
138
139 for (auto& worker : workers)
140 if (worker.joinable())
141 worker.join();
142
143 VLOG(1) << "\t Worker threads joined.";
144 }
145
146 // Allows for reusing the runtime in components that require a dispatcher
147 // to control execution of tasks.
148 std::function<void(std::function<void()>)> to_dispatcher_functional()
149 {
150 return [this](std::function<void()> task)
151 {
152 strand.post(task);
153 };
154 }
155
156 bool running;
157 boost::asio::io_service service;
158 boost::asio::io_service::strand strand;
159 boost::asio::io_service::work keep_alive;
160 std::vector<std::thread> workers;
161};
162
77location::ProgramOptions init_daemon_options()163location::ProgramOptions init_daemon_options()
78{164{
79 location::ProgramOptions options;165 location::ProgramOptions options;
@@ -193,7 +279,9 @@
193 config.provider_options.at(provider) : empty_provider_configuration);279 config.provider_options.at(provider) : empty_provider_configuration);
194280
195 if (p)281 if (p)
196 instantiated_providers.insert(p);282 instantiated_providers.insert(
283 location::DispatchingProvider::create(
284 Runtime::instance().to_dispatcher_functional(), p));
197 else285 else
198 throw std::runtime_error("Problem instantiating provider");286 throw std::runtime_error("Problem instantiating provider");
199287
@@ -203,8 +291,8 @@
203 }291 }
204 }292 }
205293
206 config.incoming->install_executor(dbus::asio::make_executor(config.incoming));294 config.incoming->install_executor(dbus::asio::make_executor(config.incoming, Runtime::instance().service));
207 config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing));295 config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing, Runtime::instance().service));
208296
209 location::service::DefaultConfiguration dc;297 location::service::DefaultConfiguration dc;
210298
@@ -222,50 +310,12 @@
222 };310 };
223311
224 auto location_service = std::make_shared<location::service::Implementation>(configuration);312 auto location_service = std::make_shared<location::service::Implementation>(configuration);
225 // We need to ensure that any exception raised by the executor does not crash the app
226 // and also gets logged.
227 auto execute = [] (std::shared_ptr<core::dbus::Bus> bus) {
228 while(true)
229 {
230 try
231 {
232 VLOG(10) << "Starting a bus executor";
233 bus->run();
234 break; // run() exited normally
235 }
236 catch (const std::exception& e)
237 {
238 LOG(WARNING) << e.what();
239 }
240 catch (...)
241 {
242 LOG(WARNING) << "Unexpected exception was raised by the bus executor";
243 }
244 }
245 };
246
247 std::thread t1{execute, config.incoming};
248 std::thread t2{execute, config.incoming};
249 std::thread t3{execute, config.incoming};
250 std::thread t4{execute, config.outgoing};
251313
252 trap->run();314 trap->run();
253315
254 config.incoming->stop();316 config.incoming->stop();
255 config.outgoing->stop();317 config.outgoing->stop();
256318
257 if (t1.joinable())
258 t1.join();
259
260 if (t2.joinable())
261 t2.join();
262
263 if (t3.joinable())
264 t3.join();
265
266 if (t4.joinable())
267 t4.join();
268
269 return EXIT_SUCCESS;319 return EXIT_SUCCESS;
270}320}
271321
272322
=== modified file 'tests/acceptance_tests.cpp'
--- tests/acceptance_tests.cpp 2015-02-13 13:19:18 +0000
+++ tests/acceptance_tests.cpp 2015-11-25 08:29:55 +0000
@@ -708,7 +708,7 @@
708708
709 options.add(Keys::update_period,709 options.add(Keys::update_period,
710 "Update period length for dummy::Provider setup.",710 "Update period length for dummy::Provider setup.",
711 std::uint32_t{100});711 std::uint32_t{10});
712712
713 options.add(Keys::client_count,713 options.add(Keys::client_count,
714 "Number of clients that should be fired up.",714 "Number of clients that should be fired up.",
@@ -761,6 +761,8 @@
761};761};
762}762}
763763
764#include "did_finish_successfully.h"
765
764TEST_F(LocationServiceStandaloneLoad, MultipleClientsConnectingAndDisconnectingWorks)766TEST_F(LocationServiceStandaloneLoad, MultipleClientsConnectingAndDisconnectingWorks)
765{767{
766 EXPECT_TRUE(trust_store_is_set_up_for_testing);768 EXPECT_TRUE(trust_store_is_set_up_for_testing);
@@ -829,7 +831,7 @@
829 status;831 status;
830 }, core::posix::StandardStream::empty);832 }, core::posix::StandardStream::empty);
831833
832 std::this_thread::sleep_for(std::chrono::seconds{2});834 std::this_thread::sleep_for(std::chrono::seconds{15});
833835
834 auto client = [this]()836 auto client = [this]()
835 {837 {
@@ -957,17 +959,11 @@
957 {959 {
958 VLOG(1) << "Stopping client...: " << client.pid();960 VLOG(1) << "Stopping client...: " << client.pid();
959 client.send_signal_or_throw(core::posix::Signal::sig_term);961 client.send_signal_or_throw(core::posix::Signal::sig_term);
960 auto result = client.wait_for(core::posix::wait::Flags::untraced);962 EXPECT_TRUE(did_finish_successfully(client.wait_for(core::posix::wait::Flags::untraced)));
961
962 EXPECT_EQ(core::posix::wait::Result::Status::exited, result.status);
963 EXPECT_EQ(core::posix::exit::Status::success, result.detail.if_exited.status);
964 }963 }
965964
966 VLOG(1) << "Cleaned up clients, shutting down the service...";965 VLOG(1) << "Cleaned up clients, shutting down the service...";
967966
968 server.send_signal_or_throw(core::posix::Signal::sig_term);967 server.send_signal_or_throw(core::posix::Signal::sig_term);
969 auto result = server.wait_for(core::posix::wait::Flags::untraced);968 EXPECT_TRUE(did_finish_successfully(server.wait_for(core::posix::wait::Flags::untraced)));
970
971 EXPECT_EQ(core::posix::wait::Result::Status::exited, result.status);
972 EXPECT_EQ(core::posix::exit::Status::success, result.detail.if_exited.status);
973}969}

Subscribers

People subscribed via source and target branches