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

Proposed by Thomas Voß
Status: Superseded
Proposed branch: lp:~thomas-voss/location-service/robustify-event-propagation-in-case-of-multiple-providers-running
Merge into: lp:location-service/trunk
Diff against target: 722 lines (+542/-48)
6 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/non_selecting_provider_selection_policy.cpp (+24/-14)
src/location_service/com/ubuntu/location/service/daemon.cpp (+91/-23)
tests/acceptance_tests.cpp (+11/-11)
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
Loïc Minier Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+238544@code.launchpad.net

This proposal has been superseded by a proposal from 2015-11-18.

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 :
review: Needs Fixing (continuous-integration)
130. By Thomas Voß

And some further fixes.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Loïc Minier (lool) wrote :

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.

133. By Thomas Voß

Explicitly stop bus instances on shut down.

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
1=== modified file 'src/location_service/com/ubuntu/location/CMakeLists.txt'
2--- src/location_service/com/ubuntu/location/CMakeLists.txt 2014-09-18 11:15:35 +0000
3+++ src/location_service/com/ubuntu/location/CMakeLists.txt 2014-10-16 16:35:27 +0000
4@@ -19,6 +19,7 @@
5 non_selecting_provider_selection_policy.cpp
6
7 criteria.cpp
8+ dispatching_provider.cpp
9 engine.cpp
10 init_and_shutdown.cpp
11 position.cpp
12
13=== added file 'src/location_service/com/ubuntu/location/dispatching_provider.cpp'
14--- src/location_service/com/ubuntu/location/dispatching_provider.cpp 1970-01-01 00:00:00 +0000
15+++ src/location_service/com/ubuntu/location/dispatching_provider.cpp 2014-10-16 16:35:27 +0000
16@@ -0,0 +1,325 @@
17+/*
18+ * Copyright © 2014 Canonical Ltd.
19+ *
20+ * This program is free software: you can redistribute it and/or modify it
21+ * under the terms of the GNU Lesser General Public License version 3,
22+ * as published by the Free Software Foundation.
23+ *
24+ * This program is distributed in the hope that it will be useful,
25+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
26+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27+ * GNU Lesser General Public License for more details.
28+ *
29+ * You should have received a copy of the GNU Lesser General Public License
30+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
31+ *
32+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
33+ */
34+
35+#include <com/ubuntu/location/dispatching_provider.h>
36+
37+#include <com/ubuntu/location/logging.h>
38+
39+#include <future>
40+
41+namespace location = com::ubuntu::location;
42+
43+location::DispatchingProvider::Ptr location::DispatchingProvider::create(
44+ const location::DispatchingProvider::Dispatcher& dispatcher,
45+ const location::Provider::Ptr& fwd)
46+{
47+ std::shared_ptr<location::DispatchingProvider> sp
48+ {
49+ new location::DispatchingProvider{dispatcher, fwd}
50+ };
51+ return sp->init();
52+}
53+
54+location::DispatchingProvider::DispatchingProvider(const location::DispatchingProvider::Dispatcher& dispatcher, const location::Provider::Ptr& fwd)
55+ : dispatcher{dispatcher},
56+ fwd{fwd}
57+{
58+ if (not dispatcher) throw std::logic_error
59+ {
60+ "com::ubuntu::location::DispatchingProvider: Cannot operate without valid dispatcher"
61+ };
62+
63+ if (not fwd) throw std::logic_error
64+ {
65+ "com::ubuntu::location::DispatchingProvider: Cannot operate without valid Provider"
66+ };
67+}
68+
69+location::DispatchingProvider::~DispatchingProvider()
70+{
71+}
72+
73+bool location::DispatchingProvider::supports(const location::Provider::Features& f) const
74+{
75+ std::promise<bool> promise;
76+ std::future<bool> future = promise.get_future();
77+
78+ dispatcher([&]()
79+ {
80+ try
81+ {
82+ promise.set_value(fwd->supports(f));
83+ } catch(const std::exception& e)
84+ {
85+ LOG(WARNING) << e.what();
86+ promise.set_exception(std::current_exception());
87+ } catch(...)
88+ {
89+ promise.set_exception(std::current_exception());
90+ }
91+ });
92+
93+ return future.get();
94+}
95+
96+bool location::DispatchingProvider::requires(const location::Provider::Requirements& r) const
97+{
98+ std::promise<bool> promise;
99+ std::future<bool> future = promise.get_future();
100+
101+ dispatcher([&]()
102+ {
103+ try
104+ {
105+ promise.set_value(fwd->requires(r));
106+ } catch(const std::exception& e)
107+ {
108+ LOG(WARNING) << e.what();
109+ promise.set_exception(std::current_exception());
110+ } catch(...)
111+ {
112+ promise.set_exception(std::current_exception());
113+ }
114+ });
115+
116+ return future.get();
117+}
118+
119+bool location::DispatchingProvider::matches_criteria(const location::Criteria& criteria)
120+{
121+ std::promise<bool> promise;
122+ std::future<bool> future = promise.get_future();
123+
124+ dispatcher([&]()
125+ {
126+ try
127+ {
128+ promise.set_value(fwd->matches_criteria(criteria));
129+ } catch(const std::exception& e)
130+ {
131+ LOG(WARNING) << e.what();
132+ promise.set_exception(std::current_exception());
133+ } catch(...)
134+ {
135+ promise.set_exception(std::current_exception());
136+ }
137+ });
138+
139+ return future.get();
140+}
141+
142+// We forward all events to the other providers.
143+void location::DispatchingProvider::on_wifi_and_cell_reporting_state_changed(location::WifiAndCellIdReportingState state)
144+{
145+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
146+ dispatcher([wp, state]()
147+ {
148+ auto sp = wp.lock();
149+
150+ if (not sp)
151+ return;
152+
153+ sp->fwd->on_wifi_and_cell_reporting_state_changed(state);
154+ });
155+}
156+
157+void location::DispatchingProvider::on_reference_location_updated(const location::Update<location::Position>& position)
158+{
159+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
160+ dispatcher([wp, position]()
161+ {
162+ auto sp = wp.lock();
163+
164+ if (not sp)
165+ return;
166+
167+ sp->fwd->on_reference_location_updated(position);
168+ });
169+}
170+
171+void location::DispatchingProvider::on_reference_velocity_updated(const location::Update<location::Velocity>& velocity)
172+{
173+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
174+ dispatcher([wp, velocity]()
175+ {
176+ auto sp = wp.lock();
177+
178+ if (not sp)
179+ return;
180+
181+ sp->fwd->on_reference_velocity_updated(velocity);
182+ });
183+}
184+
185+void location::DispatchingProvider::on_reference_heading_updated(const location::Update<location::Heading>& heading)
186+{
187+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
188+ dispatcher([wp, heading]()
189+ {
190+ auto sp = wp.lock();
191+
192+ if (not sp)
193+ sp->fwd->on_reference_heading_updated(heading);
194+ });
195+}
196+
197+// As well as the respective state change requests.
198+void location::DispatchingProvider::start_position_updates()
199+{
200+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
201+ dispatcher([wp]()
202+ {
203+ auto sp = wp.lock();
204+
205+ if (not sp)
206+ return;
207+
208+ sp->fwd->state_controller()->start_position_updates();
209+ });
210+}
211+
212+void location::DispatchingProvider::stop_position_updates()
213+{
214+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
215+ dispatcher([wp]()
216+ {
217+ auto sp = wp.lock();
218+
219+ if (not sp)
220+ return;
221+
222+ sp->fwd->state_controller()->stop_position_updates();
223+ });
224+}
225+
226+void location::DispatchingProvider::start_heading_updates()
227+{
228+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
229+ dispatcher([wp]()
230+ {
231+ auto sp = wp.lock();
232+
233+ if (not sp)
234+ return;
235+
236+ sp->fwd->state_controller()->start_heading_updates();
237+ });
238+}
239+
240+void location::DispatchingProvider::stop_heading_updates()
241+{
242+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
243+ dispatcher([wp]()
244+ {
245+ auto sp = wp.lock();
246+
247+ if (not sp)
248+ return;
249+
250+ sp->fwd->state_controller()->stop_heading_updates();
251+ });
252+}
253+
254+void location::DispatchingProvider::start_velocity_updates()
255+{
256+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
257+ dispatcher([wp]()
258+ {
259+ auto sp = wp.lock();
260+
261+ if (not sp)
262+ return;
263+
264+ sp->fwd->state_controller()->start_velocity_updates();
265+ });
266+}
267+
268+void location::DispatchingProvider::stop_velocity_updates()
269+{
270+ std::weak_ptr<location::DispatchingProvider> wp{shared_from_this()};
271+ dispatcher([wp]()
272+ {
273+ auto sp = wp.lock();
274+
275+ if (not sp)
276+ return;
277+
278+ sp->fwd->state_controller()->stop_velocity_updates();
279+ });
280+}
281+
282+location::DispatchingProvider::Ptr location::DispatchingProvider::init()
283+{
284+ auto sp = shared_from_this();
285+ std::weak_ptr<location::DispatchingProvider> wp{sp};
286+ connections.push_back(fwd->updates().position.connect([wp](const location::Update<location::Position>& update)
287+ {
288+ auto sp = wp.lock();
289+
290+ if (not sp)
291+ return;
292+
293+ sp->dispatcher([wp, update]()
294+ {
295+ auto sp = wp.lock();
296+
297+ if (not sp)
298+ return;
299+
300+ sp->mutable_updates().position(update);
301+ });
302+ }));
303+
304+ connections.push_back(fwd->updates().heading.connect([wp](const location::Update<location::Heading>& update)
305+ {
306+ auto sp = wp.lock();
307+
308+ if (not sp)
309+ return;
310+
311+ sp->dispatcher([wp, update]()
312+ {
313+ auto sp = wp.lock();
314+
315+ if (not sp)
316+ return;
317+
318+ sp->mutable_updates().heading(update);
319+ });
320+ }));
321+
322+ connections.push_back(fwd->updates().velocity.connect([wp](const location::Update<location::Velocity>& update)
323+ {
324+ auto sp = wp.lock();
325+
326+ if (not sp)
327+ return;
328+
329+ sp->dispatcher([wp, update]()
330+ {
331+ auto sp = wp.lock();
332+
333+ if (not sp)
334+ return;
335+
336+ sp->mutable_updates().velocity(update);
337+ });
338+ }));
339+
340+ return sp;
341+}
342
343=== added file 'src/location_service/com/ubuntu/location/dispatching_provider.h'
344--- src/location_service/com/ubuntu/location/dispatching_provider.h 1970-01-01 00:00:00 +0000
345+++ src/location_service/com/ubuntu/location/dispatching_provider.h 2014-10-16 16:35:27 +0000
346@@ -0,0 +1,90 @@
347+/*
348+ * Copyright © 2014 Canonical Ltd.
349+ *
350+ * This program is free software: you can redistribute it and/or modify it
351+ * under the terms of the GNU Lesser General Public License version 3,
352+ * as published by the Free Software Foundation.
353+ *
354+ * This program is distributed in the hope that it will be useful,
355+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
356+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
357+ * GNU Lesser General Public License for more details.
358+ *
359+ * You should have received a copy of the GNU Lesser General Public License
360+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
361+ *
362+ * Authored by: Thomas Voß <thomas.voss@canonical.com>
363+ */
364+
365+#ifndef LOCATION_SERVICE_COM_UBUNTU_LOCATION_DISPATCHING_PROVIDER_H_
366+#define LOCATION_SERVICE_COM_UBUNTU_LOCATION_DISPATCHING_PROVIDER_H_
367+
368+#include <com/ubuntu/location/provider.h>
369+
370+#include <functional>
371+#include <memory>
372+
373+namespace com
374+{
375+namespace ubuntu
376+{
377+namespace location
378+{
379+// A Provider implementation that wraps another provider implementation
380+// dispatching events/invocations via a Dispatcher functor. The dispatcher
381+// can either immediately process the given task or hand it over to a runtime
382+// with an associated event loop.
383+class DispatchingProvider : public Provider, public std::enable_shared_from_this<DispatchingProvider>
384+{
385+public:
386+ // To safe us some typing.
387+ typedef std::shared_ptr<DispatchingProvider> Ptr;
388+
389+ // The Dispatcher functor that is invoked for all incoming
390+ // invocations and for all events, with both of them being
391+ // wrapped as a task.
392+ typedef std::function<void()> Task;
393+ typedef std::function<void(Task)> Dispatcher;
394+
395+ // Create a new instance wired up to the given Provider instance.
396+ static DispatchingProvider::Ptr create(const Dispatcher& dispatcher, const Provider::Ptr& fwd);
397+
398+ ~DispatchingProvider() noexcept;
399+
400+ bool supports(const location::Provider::Features& f) const override;
401+ bool requires(const location::Provider::Requirements& r) const override;
402+ bool matches_criteria(const location::Criteria&) override;
403+
404+ // We forward all events to the other providers.
405+ void on_wifi_and_cell_reporting_state_changed(WifiAndCellIdReportingState state) override;
406+ void on_reference_location_updated(const location::Update<location::Position>& position) override;
407+ void on_reference_velocity_updated(const location::Update<location::Velocity>& velocity) override;
408+ void on_reference_heading_updated(const location::Update<location::Heading>& heading) override;
409+
410+ // As well as the respective state change requests.
411+ void start_position_updates() override;
412+ void stop_position_updates() override;
413+ void start_heading_updates() override;
414+ void stop_heading_updates() override;
415+ void start_velocity_updates() override;
416+ void stop_velocity_updates() override;
417+
418+private:
419+ // We want to pass ourselves around.
420+ DispatchingProvider(const Dispatcher& dispatcher, const Provider::Ptr& fwd);
421+
422+ // Two stage initialization is evil, but we are somewhat forced to do it.
423+ DispatchingProvider::Ptr init();
424+
425+ // The dispatcher we rely on to dispatch events/invocations.
426+ Dispatcher dispatcher;
427+ // The provider that we relay to/from.
428+ Provider::Ptr fwd;
429+ // We store all connections that should be cut on destruction.
430+ std::vector<core::ScopedConnection> connections;
431+};
432+}
433+}
434+}
435+
436+#endif // LOCATION_SERVICE_COM_UBUNTU_LOCATION_DISPATCHING_PROVIDER_H_
437
438=== modified file 'src/location_service/com/ubuntu/location/non_selecting_provider_selection_policy.cpp'
439--- src/location_service/com/ubuntu/location/non_selecting_provider_selection_policy.cpp 2014-09-18 11:15:35 +0000
440+++ src/location_service/com/ubuntu/location/non_selecting_provider_selection_policy.cpp 2014-10-16 16:35:27 +0000
441@@ -51,24 +51,33 @@
442 // We connect to all updates of each provider.
443 for (auto provider : BagOfProviders::providers)
444 {
445- provider->updates().position.connect([this](const location::Update<location::Position>& update)
446- {
447- mutable_updates().position(update);
448- });
449-
450- provider->updates().heading.connect([this](const location::Update<location::Heading>& update)
451- {
452- mutable_updates().heading(update);
453- });
454-
455- provider->updates().velocity.connect([this](const location::Update<location::Velocity>& update)
456- {
457- mutable_updates().velocity(update);
458- });
459+ event_connections.push_back(
460+ provider->updates().position.connect([this](const location::Update<location::Position>& update)
461+ {
462+ mutable_updates().position(update);
463+ }));
464+
465+ event_connections.push_back(
466+ provider->updates().heading.connect([this](const location::Update<location::Heading>& update)
467+ {
468+ mutable_updates().heading(update);
469+ }));
470+
471+ event_connections.push_back(
472+ provider->updates().velocity.connect([this](const location::Update<location::Velocity>& update)
473+ {
474+ mutable_updates().velocity(update);
475+ }));
476 }
477
478 }
479
480+ ~BagOfProviders()
481+ {
482+ for(auto& c : event_connections)
483+ c.disconnect();
484+ }
485+
486 // We always match :)
487 bool matches_criteria(const location::Criteria&) override
488 {
489@@ -137,6 +146,7 @@
490 }
491
492 std::set<location::Provider::Ptr> providers;
493+ std::vector<core::Connection> event_connections;
494 };
495 }
496
497
498=== modified file 'src/location_service/com/ubuntu/location/service/daemon.cpp'
499--- src/location_service/com/ubuntu/location/service/daemon.cpp 2014-09-16 21:34:33 +0000
500+++ src/location_service/com/ubuntu/location/service/daemon.cpp 2014-10-16 16:35:27 +0000
501@@ -17,6 +17,9 @@
502 */
503 #include <com/ubuntu/location/provider_factory.h>
504
505+#include <com/ubuntu/location/logging.h>
506+#include <com/ubuntu/location/dispatching_provider.h>
507+
508 #include <com/ubuntu/location/service/default_configuration.h>
509 #include <com/ubuntu/location/service/demultiplexing_reporter.h>
510 #include <com/ubuntu/location/service/ichnaea_reporter.h>
511@@ -32,6 +35,8 @@
512
513 #include <core/posix/signal.h>
514
515+#include <boost/asio.hpp>
516+
517 #include <system_error>
518 #include <thread>
519
520@@ -67,6 +72,87 @@
521 }
522 };
523
524+// We bundle our "global" runtime dependencies here, specifically
525+// a dispatcher to decouple multiple in-process providers from one
526+// another , forcing execution to a well known set of threads.
527+struct Runtime
528+{
529+ // Our default concurrency setup.
530+ static constexpr const std::uint32_t worker_threads = 2;
531+
532+ // Our global singleton instance.
533+ static Runtime& instance()
534+ {
535+ static Runtime runtime;
536+ return runtime;
537+ }
538+
539+ Runtime()
540+ : running{true},
541+ service{worker_threads},
542+ strand{service},
543+ keep_alive{service}
544+ {
545+ for (unsigned int i = 0; i < worker_threads; i++)
546+ workers.push_back(std::thread
547+ {
548+ [this]()
549+ {
550+ while(running)
551+ {
552+ try
553+ {
554+ service.run();
555+ }
556+ catch (const std::exception& e)
557+ {
558+ LOG(WARNING) << e.what();
559+ }
560+ catch (...)
561+ {
562+ LOG(WARNING) << "Unknown exception caught while executing boost::asio::io_service";
563+ }
564+ }
565+ }
566+ });
567+ }
568+
569+ ~Runtime()
570+ {
571+ stop();
572+ }
573+
574+ void stop()
575+ {
576+ VLOG(1) << __PRETTY_FUNCTION__;
577+ running = false;
578+ service.stop();
579+ VLOG(1) << "\t Service stopped.";
580+
581+ for (auto& worker : workers)
582+ if (worker.joinable())
583+ worker.join();
584+
585+ VLOG(1) << "\t Worker threads joined.";
586+ }
587+
588+ // Allows for reusing the runtime in components that require a dispatcher
589+ // to control execution of tasks.
590+ std::function<void(std::function<void()>)> to_dispatcher_functional()
591+ {
592+ return [this](std::function<void()> task)
593+ {
594+ strand.post(task);
595+ };
596+ }
597+
598+ bool running;
599+ boost::asio::io_service service;
600+ boost::asio::io_service::strand strand;
601+ boost::asio::io_service::work keep_alive;
602+ std::vector<std::thread> workers;
603+};
604+
605 location::ProgramOptions init_daemon_options()
606 {
607 location::ProgramOptions options;
608@@ -179,7 +265,9 @@
609 config.provider_options.at(provider) : empty_provider_configuration);
610
611 if (p)
612- instantiated_providers.insert(p);
613+ instantiated_providers.insert(
614+ location::DispatchingProvider::create(
615+ Runtime::instance().to_dispatcher_functional(), p));
616 else
617 throw std::runtime_error("Problem instantiating provider");
618
619@@ -190,8 +278,8 @@
620 }
621 }
622
623- config.incoming->install_executor(dbus::asio::make_executor(config.incoming));
624- config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing));
625+ config.incoming->install_executor(dbus::asio::make_executor(config.incoming, Runtime::instance().service));
626+ config.outgoing->install_executor(dbus::asio::make_executor(config.outgoing, Runtime::instance().service));
627
628 location::service::DefaultConfiguration dc;
629
630@@ -234,28 +322,8 @@
631 configuration
632 };
633
634- std::thread t1{[&config](){config.incoming->run();}};
635- std::thread t2{[&config](){config.incoming->run();}};
636- std::thread t3{[&config](){config.incoming->run();}};
637- std::thread t4{[&config](){config.outgoing->run();}};
638-
639 trap->run();
640
641- config.incoming->stop();
642- config.outgoing->stop();
643-
644- if (t1.joinable())
645- t1.join();
646-
647- if (t2.joinable())
648- t2.join();
649-
650- if (t3.joinable())
651- t3.join();
652-
653- if (t4.joinable())
654- t4.join();
655-
656 return EXIT_SUCCESS;
657 }
658
659
660=== modified file 'tests/acceptance_tests.cpp'
661--- tests/acceptance_tests.cpp 2014-08-01 12:51:25 +0000
662+++ tests/acceptance_tests.cpp 2014-10-16 16:35:27 +0000
663@@ -677,7 +677,7 @@
664
665 options.add(Keys::update_period,
666 "Update period length for dummy::Provider setup.",
667- std::uint32_t{100});
668+ std::uint32_t{10});
669
670 options.add(Keys::client_count,
671 "Number of clients that should be fired up.",
672@@ -730,6 +730,8 @@
673 };
674 }
675
676+#include "did_finish_successfully.h"
677+
678 TEST_F(LocationServiceStandaloneLoad, MultipleClientsConnectingAndDisconnectingWorks)
679 {
680 EXPECT_TRUE(trust_store_is_set_up_for_testing);
681@@ -773,7 +775,11 @@
682 config.incoming = session_bus();
683 config.outgoing = session_bus();
684 config.is_testing_enabled = false;
685- config.providers = {cul::providers::dummy::Provider::class_name()};
686+ config.providers =
687+ {
688+ cul::providers::dummy::Provider::class_name(),
689+ cul::providers::dummy::Provider::class_name()
690+ };
691 config.provider_options = provider_config;
692
693 core::posix::exit::Status status{core::posix::exit::Status::failure};
694@@ -794,7 +800,7 @@
695 status;
696 }, core::posix::StandardStream::empty);
697
698- std::this_thread::sleep_for(std::chrono::seconds{2});
699+ std::this_thread::sleep_for(std::chrono::seconds{15});
700
701 auto client = [this]()
702 {
703@@ -922,17 +928,11 @@
704 {
705 VLOG(1) << "Stopping client...: " << client.pid();
706 client.send_signal_or_throw(core::posix::Signal::sig_term);
707- auto result = client.wait_for(core::posix::wait::Flags::untraced);
708-
709- EXPECT_EQ(core::posix::wait::Result::Status::exited, result.status);
710- EXPECT_EQ(core::posix::exit::Status::success, result.detail.if_exited.status);
711+ EXPECT_TRUE(did_finish_successfully(client.wait_for(core::posix::wait::Flags::untraced)));
712 }
713
714 VLOG(1) << "Cleaned up clients, shutting down the service...";
715
716 server.send_signal_or_throw(core::posix::Signal::sig_term);
717- auto result = server.wait_for(core::posix::wait::Flags::untraced);
718-
719- EXPECT_EQ(core::posix::wait::Result::Status::exited, result.status);
720- EXPECT_EQ(core::posix::exit::Status::success, result.detail.if_exited.status);
721+ EXPECT_TRUE(did_finish_successfully(server.wait_for(core::posix::wait::Flags::untraced)));
722 }

Subscribers

People subscribed via source and target branches