Merge lp:~thomas-voss/dbus-cpp/fix-destruction-of-bus-instances into lp:dbus-cpp

Proposed by Thomas Voß
Status: Needs review
Proposed branch: lp:~thomas-voss/dbus-cpp/fix-destruction-of-bus-instances
Merge into: lp:dbus-cpp
Diff against target: 293 lines (+135/-84)
2 files modified
src/core/dbus/bus.cpp (+129/-74)
tests/executor_test.cpp (+6/-10)
To merge this branch: bzr merge lp:~thomas-voss/dbus-cpp/fix-destruction-of-bus-instances
Reviewer Review Type Date Requested Status
Manuel de la Peña (community) Approve
PS Jenkins bot continuous-integration Needs Fixing
Ricardo Mendoza Pending
Review via email: mp+224921@code.launchpad.net

Commit message

Fix core::dbus::Bus desctruction and do not call dbus_shutdown unless explicitly requested by setting the env var DBUS_CPP_ENABLE_SHUTDOWN to 1

Description of the change

Fix destruction of core::dbus::Bus instances and do not call dbus_shutdown unless explicitly requested by setting DBUS_CPP_ENABLE_SHUTDOWN to 1 in the env of the process.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Manuel de la Peña (mandel) :
review: Approve
Revision history for this message
Dimitri John Ledkov (xnox) wrote :

is this going to land?

Unmerged revisions

61. By Thomas Voß

Adjust name of env variable to DBUS_CPP_ENABLE_SHUTDOWN.

60. By Thomas Voß

Fix destruction of core::dbus::Bus instances.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/core/dbus/bus.cpp'
2--- src/core/dbus/bus.cpp 2014-04-01 09:14:20 +0000
3+++ src/core/dbus/bus.cpp 2014-06-29 04:29:39 +0000
4@@ -30,6 +30,11 @@
5
6 namespace
7 {
8+static constexpr const char* dbus_cpp_enable_shutdown_key
9+{
10+ "DBUS_CPP_ENABLE_SHUTDOWN"
11+};
12+
13 struct VTable
14 {
15 static void unregister_object_path(DBusConnection*, void* data)
16@@ -55,24 +60,20 @@
17 std::shared_ptr<core::dbus::Object> object;
18 };
19
20-DBusHandlerResult static_handle_message(
21- DBusConnection* connection,
22- DBusMessage* message,
23- void* user_data)
24-{
25- (void) connection;
26- auto thiz =
27- static_cast<core::dbus::Bus*>(user_data);
28- return static_cast<DBusHandlerResult>(
29- thiz->handle_message(
30- core::dbus::Message::from_raw_message(
31- message)));
32-}
33-
34 void init_libdbus_thread_support_and_install_shutdown_handler()
35 {
36 static std::once_flag once;
37- std::call_once(once, []() { dbus_threads_init_default(); std::atexit(dbus_shutdown); });
38+ std::call_once(once, []()
39+ {
40+ // We initialize the thread-safety support in libdbus by default.
41+ dbus_threads_init_default();
42+
43+ // And we only clean up if explicitly requested in the environment.
44+ // We account for the recommendations given in:
45+ // http://dbus.freedesktop.org/doc/api/html/group__DBusMemory.html#ga01912903e39428872920d861ef565bac
46+ if (::secure_getenv(dbus_cpp_enable_shutdown_key))
47+ ::atexit(dbus_shutdown);
48+ });
49 }
50 }
51
52@@ -101,13 +102,117 @@
53
54 struct Bus::Private
55 {
56- Private()
57- : connection(nullptr),
58- message_factory_impl(new impl::MessageFactory()),
59- message_type_router([](const Message::Ptr& msg) { return msg->type(); }),
60- signal_router([](const Message::Ptr& msg){ return msg->path(); })
61- {
62- init_libdbus_thread_support_and_install_shutdown_handler();
63+ static DBusHandlerResult static_handle_message(
64+ DBusConnection* connection,
65+ DBusMessage* message,
66+ void* user_data)
67+ {
68+ (void) connection;
69+ auto thiz =
70+ static_cast<Private*>(user_data);
71+ return static_cast<DBusHandlerResult>(
72+ thiz->handle_message(
73+ core::dbus::Message::from_raw_message(
74+ message)));
75+ }
76+
77+ static std::shared_ptr<DBusConnection> connect_to_well_known_bus(WellKnownBus bus)
78+ {
79+ Error se;
80+ std::shared_ptr<DBusConnection> result
81+ {
82+ dbus_bus_get_private(static_cast<DBusBusType>(bus), std::addressof(se.raw())),
83+ [](DBusConnection*){}
84+ };
85+
86+ if (se) throw std::runtime_error
87+ {
88+ se.print()
89+ };
90+
91+ return result;
92+ }
93+
94+ static std::shared_ptr<DBusConnection> connect_to_address(const std::string& address)
95+ {
96+ Error se;
97+ std::shared_ptr<DBusConnection> result
98+ {
99+ dbus_connection_open_private(address.c_str(), std::addressof(se.raw())),
100+ [](DBusConnection*){}
101+ };
102+
103+ if (se) throw std::runtime_error
104+ {
105+ se.print()
106+ };
107+
108+ return result;
109+ }
110+
111+ Private(const std::string& address)
112+ : connection
113+ {
114+ connect_to_address(address)
115+ },
116+ message_factory_impl(new impl::MessageFactory()),
117+ message_type_router([](const Message::Ptr& msg) { return msg->type(); }),
118+ signal_router([](const Message::Ptr& msg){ return msg->path(); })
119+ {
120+ message_type_router.install_route(
121+ Message::Type::signal,
122+ std::bind(
123+ &Bus::SignalRouter::operator(),
124+ std::ref(signal_router),
125+ std::placeholders::_1));
126+
127+ dbus_connection_add_filter(
128+ connection.get(),
129+ static_handle_message,
130+ this,
131+ nullptr);
132+
133+ init_libdbus_thread_support_and_install_shutdown_handler();
134+ dbus_connection_set_exit_on_disconnect(connection.get(), FALSE);
135+ }
136+
137+ Private(WellKnownBus bus)
138+ : connection
139+ {
140+ connect_to_well_known_bus(bus)
141+ },
142+ message_factory_impl(new impl::MessageFactory()),
143+ message_type_router([](const Message::Ptr& msg) { return msg->type(); }),
144+ signal_router([](const Message::Ptr& msg){ return msg->path(); })
145+ {
146+ message_type_router.install_route(
147+ Message::Type::signal,
148+ std::bind(
149+ &Bus::SignalRouter::operator(),
150+ std::ref(signal_router),
151+ std::placeholders::_1));
152+
153+ dbus_connection_add_filter(
154+ connection.get(),
155+ static_handle_message,
156+ this,
157+ nullptr);
158+
159+ init_libdbus_thread_support_and_install_shutdown_handler();
160+ dbus_connection_set_exit_on_disconnect(connection.get(), FALSE);
161+ }
162+
163+ ~Private()
164+ {
165+ dbus_connection_remove_filter(connection.get(), static_handle_message, this);
166+ dbus_connection_close(connection.get());
167+ dbus_connection_unref(connection.get());
168+ }
169+
170+ Bus::MessageHandlerResult handle_message(const Message::Ptr& message)
171+ {
172+ message_type_router(message);
173+ return Bus::MessageHandlerResult::not_yet_handled;
174 }
175
176 std::shared_ptr<DBusConnection> connection;
177@@ -124,30 +229,8 @@
178 }
179
180 Bus::Bus(const std::string& address)
181- : d(new Private())
182+ : d(new Private(address))
183 {
184- Error se;
185- d->connection.reset(
186- dbus_connection_open_private(address.c_str(), std::addressof(se.raw())),
187- [](DBusConnection*){}
188- );
189-
190- if (!d->connection)
191- throw std::runtime_error(se.print());
192-
193- d->message_type_router.install_route(
194- Message::Type::signal,
195- std::bind(
196- &Bus::SignalRouter::operator(),
197- std::ref(d->signal_router),
198- std::placeholders::_1));
199-
200- dbus_connection_add_filter(
201- d->connection.get(),
202- static_handle_message,
203- this,
204- nullptr);
205-
206 auto message = dbus::Message::make_method_call(
207 DBus::name(),
208 DBus::path(),
209@@ -158,43 +241,15 @@
210
211 if (reply->type() == Message::Type::error)
212 throw std::runtime_error(reply->error().print());
213-
214- dbus_connection_set_exit_on_disconnect(d->connection.get(), FALSE);
215 }
216
217 Bus::Bus(WellKnownBus bus)
218- : d(new Private())
219+ : d(new Private(bus))
220 {
221- Error se;
222- d->connection.reset(
223- dbus_bus_get_private(static_cast<DBusBusType>(bus), std::addressof(se.raw())),
224- [](DBusConnection*){}
225- );
226-
227- if (!d->connection)
228- throw std::runtime_error(se.print());
229-
230- d->message_type_router.install_route(
231- Message::Type::signal,
232- std::bind(
233- &Bus::SignalRouter::operator(),
234- std::ref(d->signal_router),
235- std::placeholders::_1));
236-
237- dbus_connection_add_filter(
238- d->connection.get(),
239- static_handle_message,
240- this,
241- nullptr);
242-
243- dbus_connection_set_exit_on_disconnect(d->connection.get(), FALSE);
244 }
245
246 Bus::~Bus() noexcept
247 {
248- dbus_connection_remove_filter(d->connection.get(), static_handle_message, this);
249- dbus_connection_close(d->connection.get());
250- dbus_connection_unref(d->connection.get());
251 }
252
253 const std::shared_ptr<MessageFactory> Bus::message_factory()
254
255=== modified file 'tests/executor_test.cpp'
256--- tests/executor_test.cpp 2014-03-05 06:58:15 +0000
257+++ tests/executor_test.cpp 2014-06-29 04:29:39 +0000
258@@ -211,14 +211,12 @@
259 {
260 auto result = stub->transact_method<test::Service::Method, int64_t>();
261
262- if (result.is_error())
263- std::cout << result.error().print() << std::endl;
264- else
265+ if (not result.is_error())
266 EXPECT_EQ(42, result.value());
267
268- } catch(const std::runtime_error& e)
269+ } catch(const std::runtime_error&)
270 {
271- std::cout << e.what() << std::endl;
272+ // We silently drop this exception.
273 }
274 }
275 });
276@@ -231,14 +229,12 @@
277 {
278 auto result = stub->transact_method<test::Service::Method, int64_t>();
279
280- if (result.is_error())
281- std::cout << result.error().print() << std::endl;
282- else
283+ if (not result.is_error())
284 EXPECT_EQ(42, result.value());
285
286- } catch(const std::runtime_error& e)
287+ } catch(const std::runtime_error&)
288 {
289- std::cout << e.what() << std::endl;
290+ // We silently drop this exception.
291 }
292 }
293 });

Subscribers

People subscribed via source and target branches