Mir

Merge lp:~andreas-pokorny/mir/unify-unwinder into lp:mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Alberto Aguirre
Approved revision: no longer in the source branch.
Merged at revision: 2727
Proposed branch: lp:~andreas-pokorny/mir/unify-unwinder
Merge into: lp:mir
Diff against target: 300 lines (+110/-87)
3 files modified
src/include/common/mir/unwind_helpers.h (+76/-0)
src/server/compositor/multi_threaded_compositor.cpp (+9/-35)
src/server/display_server.cpp (+25/-52)
To merge this branch: bzr merge lp:~andreas-pokorny/mir/unify-unwinder
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Robert Carr (community) Approve
Kevin DuBois (community) Approve
Review via email: mp+264042@code.launchpad.net

Commit message

Unifies ApplyIfUnwinding and TryButRevertIfUnwinding

The unified class template can be used with
   auto var = try_but_revert_if_unwinding(apply_function, revert_function);
or
   auto var = on_unwind(revert_function);

Description of the change

This change unifies two scope guards used to handle necessary clean-up steps in case of stack unwinding with a slightly leaner version.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

try_but_revert_if_unwinding.h
unwind_helpers.h seems a less cumbersome to remember, but lgtm.

review: Approve
Revision history for this message
Robert Carr (robertcarr) wrote :

LGTM

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'src/include/common/mir/unwind_helpers.h'
2--- src/include/common/mir/unwind_helpers.h 1970-01-01 00:00:00 +0000
3+++ src/include/common/mir/unwind_helpers.h 2015-07-07 21:13:58 +0000
4@@ -0,0 +1,76 @@
5+/*
6+ * Copyright © 2015 Canonical Ltd.
7+ *
8+ * This program is free software: you can redistribute it and/or modify it
9+ * it under the terms of the GNU Lesser General Public License version 3 as
10+ * published by the Free Software Foundation.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU Lesser General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU Lesser General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ *
20+ * Authored by: Andreas Pokorny <andreas.pokorny@canonical.com>
21+ */
22+
23+#ifndef MIR_UNWIND_HELPERS_H_
24+#define MIR_UNWIND_HELPERS_H_
25+
26+#include <stdexcept>
27+#include <iostream>
28+
29+namespace mir
30+{
31+template<typename Unwind>
32+class RevertIfUnwinding
33+{
34+public:
35+ template<typename Apply>
36+ RevertIfUnwinding(Apply && apply, Unwind&& unwind)
37+ : unwind{std::move(unwind)}
38+ {
39+ apply();
40+ }
41+
42+ RevertIfUnwinding(Unwind&& unwind)
43+ : unwind{std::move(unwind)}
44+ {
45+ }
46+
47+ RevertIfUnwinding(RevertIfUnwinding<Unwind> && rhs)
48+ : unwind{std::move(rhs.unwind)}
49+ {
50+ }
51+
52+ ~RevertIfUnwinding()
53+ {
54+ if (std::uncaught_exception())
55+ unwind();
56+ }
57+
58+private:
59+ RevertIfUnwinding(RevertIfUnwinding const&) = delete;
60+ RevertIfUnwinding& operator=(RevertIfUnwinding const&) = delete;
61+
62+ Unwind unwind;
63+};
64+
65+template<typename Apply, typename Revert>
66+inline auto try_but_revert_if_unwinding(Apply && apply, Revert && reverse) -> RevertIfUnwinding<Revert>
67+{
68+ return RevertIfUnwinding<Revert>{std::move(apply), std::move(reverse)};
69+}
70+
71+
72+template<typename Revert>
73+inline auto on_unwind(Revert && action) -> RevertIfUnwinding<Revert>
74+{
75+ return RevertIfUnwinding<Revert>{std::move(action)};
76+}
77+
78+}
79+
80+#endif
81
82=== modified file 'src/server/compositor/multi_threaded_compositor.cpp'
83--- src/server/compositor/multi_threaded_compositor.cpp 2015-06-26 08:54:18 +0000
84+++ src/server/compositor/multi_threaded_compositor.cpp 2015-07-07 21:13:58 +0000
85@@ -29,6 +29,7 @@
86 #include "mir/scene/surface.h"
87 #include "mir/terminate_with_current_exception.h"
88 #include "mir/raii.h"
89+#include "mir/unwind_helpers.h"
90 #include "mir/thread_name.h"
91
92 #include <thread>
93@@ -42,32 +43,6 @@
94 namespace mg = mir::graphics;
95 namespace ms = mir::scene;
96
97-namespace
98-{
99-
100-class ApplyIfUnwinding
101-{
102-public:
103- ApplyIfUnwinding(std::function<void()> const& apply)
104- : apply{apply}
105- {
106- }
107-
108- ~ApplyIfUnwinding()
109- {
110- if (std::uncaught_exception())
111- apply();
112- }
113-
114-private:
115- ApplyIfUnwinding(ApplyIfUnwinding const&) = delete;
116- ApplyIfUnwinding& operator=(ApplyIfUnwinding const&) = delete;
117-
118- std::function<void()> const apply;
119-};
120-
121-}
122-
123 namespace mir
124 {
125 namespace compositor
126@@ -118,12 +93,12 @@
127 void operator()() noexcept // noexcept is important! (LP: #1237332)
128 try
129 {
130- ApplyIfUnwinding on_startup_failure{
131+ auto on_startup_failure = on_unwind(
132 [this]
133 {
134 if (started_future.wait_for(0s) != std::future_status::ready)
135 started.set_exception(std::current_exception());
136- }};
137+ });
138
139 mir::set_thread_name("Mir/Comp");
140
141@@ -311,10 +286,8 @@
142 report->started();
143
144 /* To cleanup state if any code below throws */
145- ApplyIfUnwinding cleanup_if_unwinding{
146- [this, &lk]{
147- destroy_compositing_threads(lk);
148- }};
149+ auto cleanup_if_unwinding = on_unwind(
150+ [this, &lk]{ destroy_compositing_threads(lk); });
151
152 lk.unlock();
153 scene->add_observer(observer);
154@@ -341,11 +314,12 @@
155 state = CompositorState::stopping;
156
157 /* To cleanup state if any code below throws */
158- ApplyIfUnwinding cleanup_if_unwinding{
159- [this, &lk]{
160+ auto cleanup_if_unwinding = on_unwind(
161+ [this, &lk]
162+ {
163 if(!lk.owns_lock()) lk.lock();
164 state = CompositorState::started;
165- }};
166+ });
167
168 lk.unlock();
169 scene->remove_observer(observer);
170
171=== modified file 'src/server/display_server.cpp'
172--- src/server/display_server.cpp 2015-06-17 05:20:42 +0000
173+++ src/server/display_server.cpp 2015-07-07 21:13:58 +0000
174@@ -31,6 +31,7 @@
175 #include "mir/input/input_manager.h"
176 #include "mir/input/input_dispatcher.h"
177 #include "mir/log.h"
178+#include "mir/unwind_helpers.h"
179
180 #include <stdexcept>
181
182@@ -40,34 +41,6 @@
183 namespace mi = mir::input;
184 namespace msh = mir::shell;
185
186-namespace
187-{
188-
189-class TryButRevertIfUnwinding
190-{
191-public:
192- TryButRevertIfUnwinding(std::function<void()> const& apply,
193- std::function<void()> const& revert)
194- : revert{revert}
195- {
196- apply();
197- }
198-
199- ~TryButRevertIfUnwinding()
200- {
201- if (std::uncaught_exception())
202- revert();
203- }
204-
205-private:
206- TryButRevertIfUnwinding(TryButRevertIfUnwinding const&) = delete;
207- TryButRevertIfUnwinding& operator=(TryButRevertIfUnwinding const&) = delete;
208-
209- std::function<void()> const revert;
210-};
211-
212-}
213-
214 struct mir::DisplayServer::Private
215 {
216 Private(ServerConfiguration& config)
217@@ -97,29 +70,29 @@
218 {
219 try
220 {
221- TryButRevertIfUnwinding comm{
222+ auto comm = try_but_revert_if_unwinding(
223 [this] { connector->stop(); },
224- [this] { connector->start(); }};
225+ [this] { connector->start(); });
226
227- TryButRevertIfUnwinding prompt{
228+ auto prompt = try_but_revert_if_unwinding(
229 [this] { prompt_connector->stop(); },
230- [this] { prompt_connector->start(); }};
231+ [this] { prompt_connector->start(); });
232
233- TryButRevertIfUnwinding dispatcher{
234+ auto dispatcher = try_but_revert_if_unwinding(
235 [this] { input_dispatcher->stop(); },
236- [this] { input_dispatcher->start(); }};
237+ [this] { input_dispatcher->start(); });
238
239- TryButRevertIfUnwinding input{
240+ auto input = try_but_revert_if_unwinding(
241 [this] { input_manager->stop(); },
242- [this] { input_manager->start(); }};
243+ [this] { input_manager->start(); });
244
245- TryButRevertIfUnwinding display_config_processing{
246+ auto display_config_processing = try_but_revert_if_unwinding(
247 [this] { display_changer->pause_display_config_processing(); },
248- [this] { display_changer->resume_display_config_processing(); }};
249+ [this] { display_changer->resume_display_config_processing(); });
250
251- TryButRevertIfUnwinding comp{
252+ auto comp = try_but_revert_if_unwinding(
253 [this] { compositor->stop(); },
254- [this] { compositor->start(); }};
255+ [this] { compositor->start(); });
256
257 display->pause();
258 }
259@@ -137,29 +110,29 @@
260 {
261 try
262 {
263- TryButRevertIfUnwinding disp{
264+ auto disp = try_but_revert_if_unwinding(
265 [this] { display->resume(); },
266- [this] { display->pause(); }};
267+ [this] { display->pause(); });
268
269- TryButRevertIfUnwinding comp{
270+ auto comp = try_but_revert_if_unwinding(
271 [this] { compositor->start(); },
272- [this] { compositor->stop(); }};
273+ [this] { compositor->stop(); });
274
275- TryButRevertIfUnwinding display_config_processing{
276+ auto display_config_processing = try_but_revert_if_unwinding(
277 [this] { display_changer->resume_display_config_processing(); },
278- [this] { display_changer->pause_display_config_processing(); }};
279+ [this] { display_changer->pause_display_config_processing(); });
280
281- TryButRevertIfUnwinding input{
282+ auto input = try_but_revert_if_unwinding(
283 [this] { input_manager->start(); },
284- [this] { input_manager->stop(); }};
285+ [this] { input_manager->stop(); });
286
287- TryButRevertIfUnwinding dispatcher{
288+ auto dispatcher = try_but_revert_if_unwinding(
289 [this] { input_dispatcher->start(); },
290- [this] { input_dispatcher->stop(); }};
291+ [this] { input_dispatcher->stop(); });
292
293- TryButRevertIfUnwinding prompt{
294+ auto prompt = try_but_revert_if_unwinding(
295 [this] { prompt_connector->start(); },
296- [this] { prompt_connector->stop(); }};
297+ [this] { prompt_connector->stop(); });
298
299 connector->start();
300 }

Subscribers

People subscribed via source and target branches