Mir

Merge lp:~albaguirre/mir/fix-tsan-findings into lp:mir

Proposed by Alberto Aguirre
Status: Merged
Approved by: Alberto Aguirre
Approved revision: no longer in the source branch.
Merged at revision: 3199
Proposed branch: lp:~albaguirre/mir/fix-tsan-findings
Merge into: lp:mir
Diff against target: 1121 lines (+232/-340)
16 files modified
cmake/MirCommon.cmake (+3/-1)
src/server/compositor/buffer_stream_surfaces.cpp (+10/-7)
src/server/compositor/multi_threaded_compositor.cpp (+16/-11)
src/server/scene/surface_stack.cpp (+2/-1)
src/server/scene/surface_stack.h (+4/-3)
tests/acceptance-tests/test_unresponsive_client.cpp (+12/-3)
tests/include/mir/test/stub_server_tool.h (+24/-7)
tests/include/mir/test/test_protobuf_client.h (+26/-50)
tests/include/mir_test_framework/stub_input_platform.h (+2/-0)
tests/mir_test_doubles/test_protobuf_client.cpp (+86/-133)
tests/mir_test_framework/stub_input_platform.cpp (+4/-0)
tests/unit-tests/client/test_client_mir_surface.cpp (+5/-1)
tests/unit-tests/frontend/test_protobuf_reports_errors.cpp (+1/-1)
tests/unit-tests/frontend/test_protobuf_surface_apis.cpp (+3/-7)
tests/unit-tests/frontend/test_published_socket_connector.cpp (+32/-114)
tests/unit-tests/thread/test_basic_thread_pool.cpp (+2/-1)
To merge this branch: bzr merge lp:~albaguirre/mir/fix-tsan-findings
Reviewer Review Type Date Requested Status
Alan Griffiths Approve
PS Jenkins bot (community) continuous-integration Approve
Daniel van Vugt Abstain
Review via email: mp+279816@code.launchpad.net

Commit message

Fix TSan findings

Description of the change

Fix TSan findings

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
Alberto Aguirre (albaguirre) wrote :

Umm unsure if I introduced an issue or uncovered one...I'll check tomorrow.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Changes look sensible, but from multiple motivations which makes reviewing harder.

Triggering a rebuild to get another datapoint

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

^-- the xenial-amd64 failure also happens with lp:mir, it's lp:1523965

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

Sounds good.

Hopefully we'll reach a point where we're clean enough to automate this in CI...

review: Approve
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

We had a CI job that ran Thread Sanitizer with a clang build. I believe it got axed after the GCC5/clang fiasco.

So now with Jenkass we should setup a GCC TSan job.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Failed due to lots of FD leaks. Is that right?

review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I'd really like to approve a lot of these changes as they are obviously correct.

But the rework of CompositingFunctor::operator() isn't...

~~~~

+ //Appease TSan, avoid destructor and this thread accessing the same shared_ptr instance
+ auto disp_listener = std::move(display_listener);

As display_listener is const, isn't this simpler as:

    auto const disp_listener = display_listener;

Or even better, just make it a value capture in the lines below? Vis:

        auto display_registration = mir::raii::paired_calls(
            [display_listener=display_listener, &group=group]{group.for_each_display_buffer([&](mg::DisplayBuffer& buffer)
                { display_listener->add_display(buffer.view_area()); });},
            [display_listener=display_listener, &group=group]{group.for_each_display_buffer([&](mg::DisplayBuffer& buffer)
                { display_listener->remove_display(buffer.view_area()); });});

~~~~

- auto on_startup_failure = on_unwind(
- [this]
- {
- if (started_future.wait_for(0s) != std::future_status::ready)
- started.set_exception(std::current_exception());
- });
-
...
     catch(...)
     {
+ try
+ {
+ //Move the promise so that the promise destructor occurs here rather than in the thread
+ //destroying CompositingFunctor, mostly to appease TSan
+ auto promise = std::move(started);
+ promise.set_exception(std::current_exception());
+ }
+ catch(...)
+ {
+ }

So we no longer use "on_unwind()" because the destructor of the moved promise will throw after we set_exception()? And then we eat the exception anyway? That seems an overly complex mechanism to destroy CompositingFunctor::promise.

review: Needs Fixing
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

>As display_listener is const, isn't this simpler as:

> auto const disp_listener = display_listener;

The MP code I propose avoids an unnecessary ref count increase, but sure I can make that change.

>Or even better, just make it a value capture in the lines below? Vis:

You cannot capture a member variable directly; you can only through access through "this" (or by creating a local reference that the lambda can then capture).

> So we no longer use "on_unwind()" because the destructor of the moved promise
> will throw after we set_exception()? And then we eat the exception anyway?
> That seems an overly complex mechanism to destroy CompositingFunctor::promise.

No. I didn't see a need for unwind helper since we already have a catch block.

The main motivation is not removing the unwind helper, it's removing the query of std::future since it's not threadsafe (std::future sate would be accessed by two threads). Rather than synchronizing that access, I avoid querying the std::future at all. Since I won't check its status, then set_exception may throw if it already has a value and so we eat the exception.

The move of the std::promise is also to avoid two threads access std::promise state, the thread calling the destructor and the thread accessing the promise (the compositing thread).

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> >As display_listener is const, isn't this simpler as:
>
> > auto const disp_listener = display_listener;
>
> The MP code I propose avoids an unnecessary ref count increase, but sure I can
> make that change.

Don't we get a single ref count increment in both cases? The proposed version can't move from a const display_listener so an unnamed temporary is created for the move.

> >Or even better, just make it a value capture in the lines below? Vis:
>
> You cannot capture a member variable directly; you can only through access
> through "this" (or by creating a local reference that the lambda can then
> capture).

I gave the syntax I was thinking of. Admittedly, that does create two copies of display_listener.

~~~~

> > So we no longer use "on_unwind()" because the destructor of the moved
> promise
> > will throw after we set_exception()? And then we eat the exception anyway?
> > That seems an overly complex mechanism to destroy
> CompositingFunctor::promise.
>
> No. I didn't see a need for unwind helper since we already have a catch block.
>
> The main motivation is not removing the unwind helper, it's removing the query
> of std::future since it's not threadsafe (std::future sate would be accessed
> by two threads). Rather than synchronizing that access, I avoid querying the
> std::future at all. Since I won't check its status, then set_exception may
> throw if it already has a value and so we eat the exception.
>
> The move of the std::promise is also to avoid two threads access std::promise
> state, the thread calling the destructor and the thread accessing the promise
> (the compositing thread).

I need to think about this - it sounds like the wrong synchronization objects are being used.

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:3189
http://jenkins.qa.ubuntu.com/job/mir-ci/5845/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-android-vivid-i386-build/5307
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-clang-vivid-amd64-build/4213
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-vivid-touch/5256
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-xenial-touch/155/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/173
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-amd64-ci/173/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/173
        deb: http://jenkins.qa.ubuntu.com/job/mir-xenial-i386-ci/173/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5256
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-vivid-armhf/5256/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-touch/7776
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26032
    SUCCESS: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/153
        deb: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-builder-xenial-armhf/153/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/mir-mediumtests-runner-xenial-touch/12/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/26039

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/mir-ci/5845/rebuild

review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

OK, I still think the logic around started/started_future is expressed poorly, but that's pre-existing and not worth blocking on.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cmake/MirCommon.cmake'
2--- cmake/MirCommon.cmake 2015-12-14 06:21:46 +0000
3+++ cmake/MirCommon.cmake 2015-12-14 15:38:49 +0000
4@@ -74,7 +74,9 @@
5 endif()
6 endif()
7 # Space after ${TSAN_EXTRA_OPTIONS} works around bug in TSAN env. variable parsing
8- list(APPEND test_env "TSAN_OPTIONS=\"suppressions=${CMAKE_SOURCE_DIR}/tools/tsan-suppressions second_deadlock_stack=1 halt_on_error=1 history_size=7 ${TSAN_EXTRA_OPTIONS} \"")
9+ list(APPEND test_env "TSAN_OPTIONS=\"suppressions=${CMAKE_SOURCE_DIR}/tools/tsan-suppressions second_deadlock_stack=1 halt_on_error=1 history_size=7 die_after_fork=0 ${TSAN_EXTRA_OPTIONS} \"")
10+ # TSan does not support starting threads after fork
11+ set(test_exclusion_filter "ThreadedDispatcherSignalTest.keeps_dispatching_after_signal_interruption")
12 endif()
13
14 if(SYSTEM_SUPPORTS_O_TMPFILE EQUAL 1)
15
16=== modified file 'src/server/compositor/buffer_stream_surfaces.cpp'
17--- src/server/compositor/buffer_stream_surfaces.cpp 2015-11-21 00:23:00 +0000
18+++ src/server/compositor/buffer_stream_surfaces.cpp 2015-12-14 15:38:49 +0000
19@@ -59,20 +59,20 @@
20 {
21 buffer_bundle->client_release(buf);
22 {
23- std::unique_lock<std::mutex> lk(mutex);
24+ std::lock_guard<decltype(mutex)> lk(mutex);
25 first_frame_posted = true;
26 }
27 }
28
29 geom::Size mc::BufferStreamSurfaces::stream_size()
30 {
31- std::unique_lock<std::mutex> lk(mutex);
32+ std::lock_guard<decltype(mutex)> lk(mutex);
33 return logical_size;
34 }
35
36 void mc::BufferStreamSurfaces::resize(geom::Size const& size)
37 {
38- std::unique_lock<std::mutex> lk(mutex);
39+ std::lock_guard<decltype(mutex)> lk(mutex);
40 logical_size = size;
41 buffer_bundle->resize(logical_size * scale);
42 }
43@@ -117,14 +117,17 @@
44
45 bool mc::BufferStreamSurfaces::has_submitted_buffer() const
46 {
47- std::unique_lock<std::mutex> lk(mutex);
48+ std::lock_guard<decltype(mutex)> lk(mutex);
49 return first_frame_posted;
50 }
51
52 void mc::BufferStreamSurfaces::with_most_recent_buffer_do(std::function<void(graphics::Buffer&)> const& exec)
53 {
54- if (!first_frame_posted)
55- BOOST_THROW_EXCEPTION(std::runtime_error("No frame posted yet"));
56+ {
57+ std::lock_guard<decltype(mutex)> lk(mutex);
58+ if (!first_frame_posted)
59+ BOOST_THROW_EXCEPTION(std::runtime_error("No frame posted yet"));
60+ }
61 exec(*std::make_shared<mc::TemporarySnapshotBuffer>(buffer_bundle));
62 }
63
64@@ -164,7 +167,7 @@
65 if (new_scale <= 0.0f)
66 BOOST_THROW_EXCEPTION(std::logic_error("invalid scale (must be greater than zero)"));
67
68- std::unique_lock<std::mutex> lk(mutex);
69+ std::lock_guard<decltype(mutex)> lk(mutex);
70 scale = new_scale;
71 buffer_bundle->resize(logical_size * scale);
72 }
73
74=== modified file 'src/server/compositor/multi_threaded_compositor.cpp'
75--- src/server/compositor/multi_threaded_compositor.cpp 2015-09-22 14:53:26 +0000
76+++ src/server/compositor/multi_threaded_compositor.cpp 2015-12-14 15:38:49 +0000
77@@ -73,13 +73,6 @@
78 void operator()() noexcept // noexcept is important! (LP: #1237332)
79 try
80 {
81- auto on_startup_failure = on_unwind(
82- [this]
83- {
84- if (started_future.wait_for(0s) != std::future_status::ready)
85- started.set_exception(std::current_exception());
86- });
87-
88 mir::set_thread_name("Mir/Comp");
89
90 std::vector<std::tuple<mg::DisplayBuffer*, std::unique_ptr<mc::DisplayBufferCompositor>>> compositors;
91@@ -96,11 +89,13 @@
92 CompositorReport::SubCompositorId{comp_id});
93 });
94
95+ //Appease TSan, avoid destructor and this thread accessing the same shared_ptr instance
96+ auto const disp_listener = display_listener;
97 auto display_registration = mir::raii::paired_calls(
98- [this]{group.for_each_display_buffer([this](mg::DisplayBuffer& buffer)
99- { display_listener->add_display(buffer.view_area()); });},
100- [this]{group.for_each_display_buffer([this](mg::DisplayBuffer& buffer)
101- { display_listener->remove_display(buffer.view_area()); });});
102+ [this, &disp_listener]{group.for_each_display_buffer([&disp_listener](mg::DisplayBuffer& buffer)
103+ { disp_listener->add_display(buffer.view_area()); });},
104+ [this, &disp_listener]{group.for_each_display_buffer([&disp_listener](mg::DisplayBuffer& buffer)
105+ { disp_listener->remove_display(buffer.view_area()); });});
106
107 auto compositor_registration = mir::raii::paired_calls(
108 [this,&compositors]
109@@ -179,6 +174,16 @@
110 }
111 catch(...)
112 {
113+ try
114+ {
115+ //Move the promise so that the promise destructor occurs here rather than in the thread
116+ //destroying CompositingFunctor, mostly to appease TSan
117+ auto promise = std::move(started);
118+ promise.set_exception(std::current_exception());
119+ }
120+ catch(...)
121+ {
122+ }
123 mir::terminate_with_current_exception();
124 }
125
126
127=== modified file 'src/server/scene/surface_stack.cpp'
128--- src/server/scene/surface_stack.cpp 2015-12-03 23:57:09 +0000
129+++ src/server/scene/surface_stack.cpp 2015-12-14 15:38:49 +0000
130@@ -121,7 +121,8 @@
131
132 ms::SurfaceStack::SurfaceStack(
133 std::shared_ptr<SceneReport> const& report) :
134- report{report}
135+ report{report},
136+ scene_changed{false}
137 {
138 }
139
140
141=== modified file 'src/server/scene/surface_stack.h'
142--- src/server/scene/surface_stack.h 2015-12-03 10:28:45 +0000
143+++ src/server/scene/surface_stack.h 2015-12-14 15:38:49 +0000
144@@ -28,11 +28,12 @@
145
146 #include "mir/basic_observers.h"
147
148+#include <atomic>
149+#include <map>
150 #include <memory>
151-#include <vector>
152 #include <mutex>
153-#include <map>
154 #include <set>
155+#include <vector>
156
157 namespace mir
158 {
159@@ -119,7 +120,7 @@
160 std::vector<std::shared_ptr<graphics::Renderable>> overlays;
161
162 Observers observers;
163- bool scene_changed = false;
164+ std::atomic<bool> scene_changed;
165 };
166
167 }
168
169=== modified file 'tests/acceptance-tests/test_unresponsive_client.cpp'
170--- tests/acceptance-tests/test_unresponsive_client.cpp 2015-07-28 09:09:00 +0000
171+++ tests/acceptance-tests/test_unresponsive_client.cpp 2015-12-14 15:38:49 +0000
172@@ -32,8 +32,9 @@
173 #include <gtest/gtest.h>
174 #include <gmock/gmock.h>
175
176+#include <future>
177+#include <mutex>
178 #include <string>
179-#include <future>
180
181 namespace ms = mir::scene;
182 namespace mt = mir::test;
183@@ -45,19 +46,27 @@
184 {
185 struct SessionListener : ms::NullSessionListener
186 {
187+ ~SessionListener()
188+ {
189+ std::lock_guard<decltype(guard)> lk{guard};
190+ sessions.clear();
191+ }
192+
193 void starting(std::shared_ptr<ms::Session> const& session) override
194- { sessions.insert(session); }
195+ { std::lock_guard<decltype(guard)> lk{guard}; sessions.insert(session); }
196
197 void stopping(std::shared_ptr<ms::Session> const& session) override
198- { sessions.erase(session); }
199+ { std::lock_guard<decltype(guard)> lk{guard}; sessions.erase(session); }
200
201 void for_each(std::function<void(std::shared_ptr<ms::Session> const&)> f) const
202 {
203+ std::lock_guard<decltype(guard)> lk{guard};
204 for (auto& session : sessions)
205 f(session);
206 }
207
208 private:
209+ std::mutex mutable guard;
210 std::set<std::shared_ptr<ms::Session>> sessions;
211 };
212 }
213
214=== modified file 'tests/include/mir/test/stub_server_tool.h'
215--- tests/include/mir/test/stub_server_tool.h 2015-09-18 14:44:59 +0000
216+++ tests/include/mir/test/stub_server_tool.h 2015-12-14 15:38:49 +0000
217@@ -44,8 +44,8 @@
218 response->set_pixel_format(request->pixel_format());
219 response->mutable_buffer()->set_buffer_id(22);
220
221- std::unique_lock<std::mutex> lock(guard);
222- surface_name = request->surface_name();
223+ std::lock_guard<std::mutex> lock(guard);
224+ surf_name = request->surface_name();
225 wait_condition.notify_one();
226
227 done->Run();
228@@ -58,7 +58,8 @@
229 {
230 response->set_buffer_id(22);
231
232- std::unique_lock<std::mutex> lock(guard);
233+ std::lock_guard<std::mutex> lock(guard);
234+ //FIXME: huh? What's the condition here?
235 wait_condition.notify_one();
236 done->Run();
237 }
238@@ -78,7 +79,10 @@
239 mir::protobuf::Connection* connect_msg,
240 google::protobuf::Closure* done) override
241 {
242- app_name = request->application_name();
243+ {
244+ std::lock_guard<std::mutex> lock(guard);
245+ app_name = request->application_name();
246+ }
247 // If you check out MirConnection::connected either the platform and display_configuration
248 // have to be set or the error has to be set, otherwise we die and fail to callback.
249 //
250@@ -95,7 +99,8 @@
251 mir::protobuf::Void* /*response*/,
252 google::protobuf::Closure* done) override
253 {
254- std::unique_lock<std::mutex> lock(guard);
255+ std::lock_guard<std::mutex> lock(guard);
256+ //FIXME: huh? What's the condition here?
257 wait_condition.notify_one();
258 done->Run();
259 }
260@@ -108,8 +113,20 @@
261 done->Run();
262 }
263
264- std::mutex guard;
265- std::string surface_name;
266+ std::string application_name() const
267+ {
268+ std::lock_guard<std::mutex> lock(guard);
269+ return app_name;
270+ }
271+
272+ std::string surface_name() const
273+ {
274+ std::lock_guard<std::mutex> lock(guard);
275+ return surf_name;
276+ }
277+
278+ std::mutex mutable guard;
279+ std::string surf_name;
280 std::condition_variable wait_condition;
281 std::string app_name;
282 };
283
284=== modified file 'tests/include/mir/test/test_protobuf_client.h'
285--- tests/include/mir/test/test_protobuf_client.h 2015-09-18 14:44:59 +0000
286+++ tests/include/mir/test/test_protobuf_client.h 2015-12-14 15:38:49 +0000
287@@ -26,8 +26,10 @@
288
289 #include <gmock/gmock.h>
290
291-#include <memory>
292-#include <atomic>
293+#include <condition_variable>
294+#include <functional>
295+#include <mutex>
296+#include <string>
297
298 namespace mir
299 {
300@@ -63,69 +65,43 @@
301 MOCK_METHOD0(connect_done, void());
302 MOCK_METHOD0(create_surface_done, void());
303 MOCK_METHOD0(next_buffer_done, void());
304- MOCK_METHOD0(exchange_buffer_done, void());
305- MOCK_METHOD0(release_surface_done, void());
306 MOCK_METHOD0(disconnect_done, void());
307 MOCK_METHOD0(display_configure_done, void());
308- MOCK_METHOD0(prompt_session_start_done, void());
309- MOCK_METHOD0(prompt_session_stop_done, void());
310
311 void on_connect_done();
312-
313 void on_create_surface_done();
314-
315 void on_next_buffer_done();
316-
317- void on_exchange_buffer_done();
318-
319- void on_release_surface_done();
320-
321 void on_disconnect_done();
322-
323 void on_configure_display_done();
324
325+ void connect();
326+ void disconnect();
327+ void create_surface();
328+ void next_buffer();
329+ void configure_display();
330+
331 void wait_for_connect_done();
332-
333 void wait_for_create_surface();
334-
335 void wait_for_next_buffer();
336-
337- void wait_for_exchange_buffer();
338-
339- void wait_for_release_surface();
340-
341 void wait_for_disconnect_done();
342-
343+ void wait_for_configure_display_done();
344 void wait_for_surface_count(int count);
345
346- void wait_for_disconnect_count(int count);
347-
348- void tfd_done();
349-
350- void wait_for_tfd_done();
351-
352- void wait_for_configure_display_done();
353-
354- void wait_for_prompt_session_start_done();
355-
356- void wait_for_prompt_session_stop_done();
357-
358- const int maxwait;
359- std::atomic<bool> connect_done_called;
360- std::atomic<bool> create_surface_called;
361- std::atomic<bool> next_buffer_called;
362- std::atomic<bool> exchange_buffer_called;
363- std::atomic<bool> release_surface_called;
364- std::atomic<bool> disconnect_done_called;
365- std::atomic<bool> configure_display_done_called;
366- std::atomic<bool> tfd_done_called;
367-
368- WaitCondition wc_prompt_session_start;
369- WaitCondition wc_prompt_session_stop;
370-
371- std::atomic<int> connect_done_count;
372- std::atomic<int> create_surface_done_count;
373- std::atomic<int> disconnect_done_count;
374+ void wait_for(std::function<bool()> const& predicate, std::string const& error_message);
375+ void signal_condition(bool& condition);
376+ void reset_condition(bool& condition);
377+
378+ int const maxwait;
379+ bool connect_done_called;
380+ bool create_surface_called;
381+ bool next_buffer_called;
382+ bool exchange_buffer_called;
383+ bool disconnect_done_called;
384+ bool configure_display_done_called;
385+ int create_surface_done_count;
386+
387+ std::mutex mutable guard;
388+ std::condition_variable cv;
389 };
390 }
391 }
392
393=== modified file 'tests/include/mir_test_framework/stub_input_platform.h'
394--- tests/include/mir_test_framework/stub_input_platform.h 2015-10-14 15:22:39 +0000
395+++ tests/include/mir_test_framework/stub_input_platform.h 2015-12-14 15:38:49 +0000
396@@ -21,6 +21,7 @@
397 #include "mir/input/platform.h"
398 #include <atomic>
399 #include <memory>
400+#include <mutex>
401 #include <vector>
402
403 namespace mir
404@@ -59,6 +60,7 @@
405 std::shared_ptr<mir::input::InputDeviceRegistry> const registry;
406 static std::atomic<StubInputPlatform*> stub_input_platform;
407 static std::vector<std::weak_ptr<mir::input::InputDevice>> device_store;
408+ static std::mutex device_store_guard;
409 };
410
411 }
412
413=== modified file 'tests/mir_test_doubles/test_protobuf_client.cpp'
414--- tests/mir_test_doubles/test_protobuf_client.cpp 2015-09-18 14:44:59 +0000
415+++ tests/mir_test_doubles/test_protobuf_client.cpp 2015-12-14 15:38:49 +0000
416@@ -29,15 +29,16 @@
417 #include "mir/dispatch/threaded_dispatcher.h"
418 #include "mir/events/event_private.h"
419
420+#include <boost/throw_exception.hpp>
421+
422+#include <stdexcept>
423 #include <thread>
424
425 namespace mtd = mir::test::doubles;
426 namespace mclr = mir::client::rpc;
427 namespace md = mir::dispatch;
428
429-mir::test::TestProtobufClient::TestProtobufClient(
430- std::string socket_file,
431- int timeout_ms) :
432+mir::test::TestProtobufClient::TestProtobufClient(std::string socket_file, int timeout_ms) :
433 rpc_report(std::make_shared<testing::NiceMock<doubles::MockRpcReport>>()),
434 channel(mclr::make_rpc_channel(
435 socket_file,
436@@ -54,13 +55,9 @@
437 create_surface_called(false),
438 next_buffer_called(false),
439 exchange_buffer_called(false),
440- release_surface_called(false),
441 disconnect_done_called(false),
442 configure_display_done_called(false),
443- tfd_done_called(false),
444- connect_done_count(0),
445- create_surface_done_count(0),
446- disconnect_done_count(0)
447+ create_surface_done_count(0)
448 {
449 surface_parameters.set_width(640);
450 surface_parameters.set_height(480);
451@@ -76,177 +73,133 @@
452 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_create_surface_done));
453 ON_CALL(*this, next_buffer_done())
454 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_next_buffer_done));
455- ON_CALL(*this, exchange_buffer_done())
456- .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_exchange_buffer_done));
457- ON_CALL(*this, release_surface_done())
458- .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_release_surface_done));
459 ON_CALL(*this, disconnect_done())
460 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_disconnect_done));
461 ON_CALL(*this, display_configure_done())
462 .WillByDefault(testing::Invoke(this, &TestProtobufClient::on_configure_display_done));
463- ON_CALL(*this, prompt_session_start_done())
464- .WillByDefault(testing::Invoke(&wc_prompt_session_start, &WaitCondition::wake_up_everyone));
465- ON_CALL(*this, prompt_session_stop_done())
466- .WillByDefault(testing::Invoke(&wc_prompt_session_stop, &WaitCondition::wake_up_everyone));
467+}
468+
469+void mir::test::TestProtobufClient::signal_condition(bool& condition)
470+{
471+ std::lock_guard<decltype(guard)> lk{guard};
472+ condition = true;
473+ cv.notify_all();
474+}
475+
476+void mir::test::TestProtobufClient::reset_condition(bool& condition)
477+{
478+ std::lock_guard<decltype(guard)> lk{guard};
479+ condition = false;
480 }
481
482 void mir::test::TestProtobufClient::on_connect_done()
483 {
484- connect_done_called.store(true);
485-
486- auto old = connect_done_count.load();
487-
488- while (!connect_done_count.compare_exchange_weak(old, old+1));
489+ signal_condition(connect_done_called);
490 }
491
492 void mir::test::TestProtobufClient::on_create_surface_done()
493 {
494- create_surface_called.store(true);
495-
496- auto old = create_surface_done_count.load();
497-
498- while (!create_surface_done_count.compare_exchange_weak(old, old+1));
499+ std::lock_guard<decltype(guard)> lk{guard};
500+ create_surface_called = true;
501+ create_surface_done_count++;
502+ cv.notify_all();
503 }
504
505 void mir::test::TestProtobufClient::on_next_buffer_done()
506 {
507- next_buffer_called.store(true);
508-}
509-
510-void mir::test::TestProtobufClient::on_exchange_buffer_done()
511-{
512- exchange_buffer_called.store(true);
513-}
514-
515-void mir::test::TestProtobufClient::on_release_surface_done()
516-{
517- release_surface_called.store(true);
518+ signal_condition(next_buffer_called);
519 }
520
521 void mir::test::TestProtobufClient::on_disconnect_done()
522 {
523- disconnect_done_called.store(true);
524-
525- auto old = disconnect_done_count.load();
526-
527- while (!disconnect_done_count.compare_exchange_weak(old, old+1));
528+ signal_condition(disconnect_done_called);
529 }
530
531 void mir::test::TestProtobufClient::on_configure_display_done()
532 {
533- configure_display_done_called.store(true);
534+ signal_condition(configure_display_done_called);
535+}
536+
537+void mir::test::TestProtobufClient::connect()
538+{
539+ reset_condition(connect_done_called);
540+ display_server.connect(
541+ &connect_parameters,
542+ &connection,
543+ google::protobuf::NewCallback(this, &TestProtobufClient::connect_done));
544+}
545+
546+void mir::test::TestProtobufClient::disconnect()
547+{
548+ reset_condition(disconnect_done_called);
549+ display_server.disconnect(
550+ &ignored,
551+ &ignored,
552+ google::protobuf::NewCallback(this, &TestProtobufClient::disconnect_done));
553+}
554+
555+void mir::test::TestProtobufClient::create_surface()
556+{
557+ reset_condition(create_surface_called);
558+ display_server.create_surface(
559+ &surface_parameters,
560+ &surface,
561+ google::protobuf::NewCallback(this, &TestProtobufClient::create_surface_done));
562+}
563+
564+void mir::test::TestProtobufClient::next_buffer()
565+{
566+ reset_condition(next_buffer_called);
567+ display_server.next_buffer(
568+ &surface.id(),
569+ surface.mutable_buffer(),
570+ google::protobuf::NewCallback(this, &TestProtobufClient::next_buffer_done));
571+}
572+
573+void mir::test::TestProtobufClient::configure_display()
574+{
575+ reset_condition(configure_display_done_called);
576+ display_server.configure_display(
577+ &disp_config,
578+ &disp_config_response,
579+ google::protobuf::NewCallback(this, &TestProtobufClient::display_configure_done));
580 }
581
582 void mir::test::TestProtobufClient::wait_for_configure_display_done()
583 {
584- for (int i = 0; !configure_display_done_called.load() && i < maxwait; ++i)
585- {
586- std::this_thread::sleep_for(std::chrono::milliseconds(1));
587- std::this_thread::yield();
588- }
589-
590- configure_display_done_called.store(false);
591+ wait_for([this]{ return configure_display_done_called; }, "Timed out waiting to configure display");
592 }
593
594 void mir::test::TestProtobufClient::wait_for_connect_done()
595 {
596- for (int i = 0; !connect_done_called.load() && i < maxwait; ++i)
597- {
598- std::this_thread::sleep_for(std::chrono::milliseconds(1));
599- std::this_thread::yield();
600- }
601-
602- connect_done_called.store(false);
603+ wait_for([this]{ return connect_done_called; }, "Timed out waiting to connect");
604 }
605
606 void mir::test::TestProtobufClient::wait_for_create_surface()
607 {
608- for (int i = 0; !create_surface_called.load() && i < maxwait; ++i)
609- {
610- std::this_thread::sleep_for(std::chrono::milliseconds(1));
611- std::this_thread::yield();
612- }
613- create_surface_called.store(false);
614+ wait_for([this]{ return create_surface_called; }, "Timed out waiting create surface");
615 }
616
617 void mir::test::TestProtobufClient::wait_for_next_buffer()
618 {
619- for (int i = 0; !next_buffer_called.load() && i < maxwait; ++i)
620- {
621- std::this_thread::sleep_for(std::chrono::milliseconds(1));
622- std::this_thread::yield();
623- }
624- next_buffer_called.store(false);
625-}
626-
627-void mir::test::TestProtobufClient::wait_for_exchange_buffer()
628-{
629- for (int i = 0; !exchange_buffer_called.load() && i < maxwait; ++i)
630- {
631- std::this_thread::sleep_for(std::chrono::milliseconds(1));
632- std::this_thread::yield();
633- }
634- exchange_buffer_called.store(false);
635-}
636-
637-void mir::test::TestProtobufClient::wait_for_release_surface()
638-{
639- for (int i = 0; !release_surface_called.load() && i < maxwait; ++i)
640- {
641- std::this_thread::sleep_for(std::chrono::milliseconds(1));
642- std::this_thread::yield();
643- }
644- release_surface_called.store(false);
645+ wait_for([this] { return next_buffer_called; }, "Timed out waiting for next buffer");
646 }
647
648 void mir::test::TestProtobufClient::wait_for_disconnect_done()
649 {
650- for (int i = 0; !disconnect_done_called.load() && i < maxwait; ++i)
651- {
652- std::this_thread::sleep_for(std::chrono::milliseconds(1));
653- std::this_thread::yield();
654- }
655- disconnect_done_called.store(false);
656+ wait_for([this] { return disconnect_done_called; }, "Timed out waiting to disconnect");
657 }
658
659 void mir::test::TestProtobufClient::wait_for_surface_count(int count)
660 {
661- for (int i = 0; count != create_surface_done_count.load() && i < 10000; ++i)
662- {
663- std::this_thread::sleep_for(std::chrono::milliseconds(10));
664- std::this_thread::yield();
665- }
666-}
667-
668-void mir::test::TestProtobufClient::wait_for_disconnect_count(int count)
669-{
670- for (int i = 0; count != disconnect_done_count.load() && i < 10000; ++i)
671- {
672- std::this_thread::sleep_for(std::chrono::milliseconds(10));
673- std::this_thread::yield();
674- }
675-}
676-
677-void mir::test::TestProtobufClient::tfd_done()
678-{
679- tfd_done_called.store(true);
680-}
681-
682-void mir::test::TestProtobufClient::wait_for_tfd_done()
683-{
684- for (int i = 0; !tfd_done_called.load() && i < maxwait; ++i)
685- {
686- std::this_thread::sleep_for(std::chrono::milliseconds(1));
687- }
688- tfd_done_called.store(false);
689-}
690-
691-void mir::test::TestProtobufClient::wait_for_prompt_session_start_done()
692-{
693- wc_prompt_session_start.wait_for_at_most_seconds(maxwait);
694-}
695-
696-void mir::test::TestProtobufClient::wait_for_prompt_session_stop_done()
697-{
698- wc_prompt_session_stop.wait_for_at_most_seconds(maxwait);
699+ wait_for([this, count] { return create_surface_done_count == count; }, "Timed out waiting for surface count");
700+}
701+
702+void mir::test::TestProtobufClient::wait_for(std::function<bool()> const& predicate, std::string const& error_message)
703+{
704+ std::unique_lock<decltype(guard)> lk{guard};
705+ if (!cv.wait_for(lk, std::chrono::milliseconds(maxwait), predicate))
706+ {
707+ BOOST_THROW_EXCEPTION(std::runtime_error(error_message));
708+ }
709 }
710
711=== modified file 'tests/mir_test_framework/stub_input_platform.cpp'
712--- tests/mir_test_framework/stub_input_platform.cpp 2015-10-14 15:22:39 +0000
713+++ tests/mir_test_framework/stub_input_platform.cpp 2015-12-14 15:38:49 +0000
714@@ -40,12 +40,14 @@
715
716 mtf::StubInputPlatform::~StubInputPlatform()
717 {
718+ std::lock_guard<decltype(device_store_guard)> lk{device_store_guard};
719 device_store.clear();
720 stub_input_platform = nullptr;
721 }
722
723 void mtf::StubInputPlatform::start()
724 {
725+ std::lock_guard<decltype(device_store_guard)> lk{device_store_guard};
726 for (auto const& dev : device_store)
727 {
728 auto device = dev.lock();
729@@ -74,6 +76,7 @@
730 auto input_platform = stub_input_platform.load();
731 if (!input_platform)
732 {
733+ std::lock_guard<decltype(device_store_guard)> lk{device_store_guard};
734 device_store.push_back(dev);
735 return;
736 }
737@@ -118,3 +121,4 @@
738
739 std::atomic<mtf::StubInputPlatform*> mtf::StubInputPlatform::stub_input_platform{nullptr};
740 std::vector<std::weak_ptr<mir::input::InputDevice>> mtf::StubInputPlatform::device_store;
741+std::mutex mtf::StubInputPlatform::device_store_guard;
742
743=== modified file 'tests/unit-tests/client/test_client_mir_surface.cpp'
744--- tests/unit-tests/client/test_client_mir_surface.cpp 2015-12-08 15:02:49 +0000
745+++ tests/unit-tests/client/test_client_mir_surface.cpp 2015-12-14 15:38:49 +0000
746@@ -98,7 +98,11 @@
747 google::protobuf::Closure* done) override
748 {
749 create_surface_response(response);
750- surface_name = request->surface_name();
751+ {
752+ std::lock_guard<std::mutex> lock(guard);
753+ surf_name = request->surface_name();
754+ }
755+
756 done->Run();
757 }
758
759
760=== modified file 'tests/unit-tests/frontend/test_protobuf_reports_errors.cpp'
761--- tests/unit-tests/frontend/test_protobuf_reports_errors.cpp 2015-07-28 20:51:25 +0000
762+++ tests/unit-tests/frontend/test_protobuf_reports_errors.cpp 2015-12-14 15:38:49 +0000
763@@ -81,7 +81,7 @@
764 {
765 stub_services = std::make_shared<mt::ErrorServer>();
766 server = std::make_shared<mt::TestProtobufServer>("./test_error_fixture", stub_services);
767- client = std::make_shared<mt::TestProtobufClient>("./test_error_fixture", 100);
768+ client = std::make_shared<mt::TestProtobufClient>("./test_error_fixture", 10000);
769 server->comm->start();
770 }
771
772
773=== modified file 'tests/unit-tests/frontend/test_protobuf_surface_apis.cpp'
774--- tests/unit-tests/frontend/test_protobuf_surface_apis.cpp 2015-07-28 20:51:25 +0000
775+++ tests/unit-tests/frontend/test_protobuf_surface_apis.cpp 2015-12-14 15:38:49 +0000
776@@ -85,7 +85,7 @@
777
778 stub_server->comm->start();
779
780- stub_client = std::make_shared<mt::TestProtobufClient>(mtf::test_socket_file(), 100);
781+ stub_client = std::make_shared<mt::TestProtobufClient>(mtf::test_socket_file(), 10000);
782 stub_client->connect_parameters.set_application_name(__PRETTY_FUNCTION__);
783 }
784
785@@ -136,11 +136,7 @@
786
787 for (int i = 0; i != surface_count; ++i)
788 {
789- stub_client->display_server.create_surface(
790- &stub_client->surface_parameters,
791- &stub_client->surface,
792- google::protobuf::NewCallback(stub_client.get(), &mt::TestProtobufClient::create_surface_done));
793-
794+ stub_client->create_surface();
795 stub_client->wait_for_create_surface();
796 }
797
798@@ -182,7 +178,7 @@
799
800 for(int i=0; i<number_of_clients; i++)
801 {
802- auto client_tmp = std::make_shared<mt::TestProtobufClient>(mtf::test_socket_file(), 100);
803+ auto client_tmp = std::make_shared<mt::TestProtobufClient>(mtf::test_socket_file(), 10000);
804 clients.push_back(client_tmp);
805 }
806 }
807
808=== modified file 'tests/unit-tests/frontend/test_published_socket_connector.cpp'
809--- tests/unit-tests/frontend/test_published_socket_connector.cpp 2015-09-18 14:44:59 +0000
810+++ tests/unit-tests/frontend/test_published_socket_connector.cpp 2015-12-14 15:38:49 +0000
811@@ -29,20 +29,21 @@
812
813 #include "mir_protobuf.pb.h"
814
815-#include "mir/test/doubles/stub_ipc_factory.h"
816-#include "mir/test/doubles/stub_session_authorizer.h"
817-#include "mir/test/doubles/mock_rpc_report.h"
818 #include "mir/test/stub_server_tool.h"
819 #include "mir/test/test_protobuf_client.h"
820 #include "mir/test/test_protobuf_server.h"
821+#include "mir/test/wait_condition.h"
822+#include "mir/test/doubles/stub_ipc_factory.h"
823+#include "mir/test/doubles/stub_session_authorizer.h"
824+#include "mir/test/doubles/mock_rpc_report.h"
825 #include "mir/test/doubles/stub_ipc_factory.h"
826 #include "mir_test_framework/testing_server_configuration.h"
827
828 #include <gtest/gtest.h>
829 #include <gmock/gmock.h>
830
831+#include <memory>
832 #include <stdexcept>
833-#include <memory>
834 #include <string>
835
836 namespace mf = mir::frontend;
837@@ -139,11 +140,7 @@
838 {
839 EXPECT_CALL(*client, create_surface_done()).Times(1);
840
841- client->display_server.create_surface(
842- &client->surface_parameters,
843- &client->surface,
844- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::create_surface_done));
845-
846+ client->create_surface();
847 client->wait_for_create_surface();
848 }
849
850@@ -153,14 +150,10 @@
851
852 client->connect_parameters.set_application_name(__PRETTY_FUNCTION__);
853
854- client->display_server.connect(
855- &client->connect_parameters,
856- &client->connection,
857- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::connect_done));
858-
859+ client->connect();
860 client->wait_for_connect_done();
861
862- EXPECT_EQ(__PRETTY_FUNCTION__, stub_server_tool->app_name);
863+ EXPECT_EQ(__PRETTY_FUNCTION__, stub_server_tool->application_name());
864 }
865
866 TEST_F(PublishedSocketConnector, create_surface_sets_surface_name)
867@@ -170,36 +163,23 @@
868
869 client->connect_parameters.set_application_name(__PRETTY_FUNCTION__);
870
871- client->display_server.connect(
872- &client->connect_parameters,
873- &client->connection,
874- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::connect_done));
875-
876+ client->connect();
877 client->wait_for_connect_done();
878
879 client->surface_parameters.set_surface_name(__PRETTY_FUNCTION__);
880
881- client->display_server.create_surface(
882- &client->surface_parameters,
883- &client->surface,
884- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::create_surface_done));
885-
886+ client->create_surface();
887 client->wait_for_create_surface();
888
889- EXPECT_EQ(__PRETTY_FUNCTION__, stub_server_tool->surface_name);
890+ EXPECT_EQ(__PRETTY_FUNCTION__, stub_server_tool->surface_name());
891 }
892
893-
894 TEST_F(PublishedSocketConnector,
895 create_surface_results_in_a_surface_being_created)
896 {
897 EXPECT_CALL(*client, create_surface_done()).Times(1);
898
899- client->display_server.create_surface(
900- &client->surface_parameters,
901- &client->surface,
902- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::create_surface_done));
903-
904+ client->create_surface();
905 client->wait_for_create_surface();
906 }
907
908@@ -218,19 +198,11 @@
909 using namespace testing;
910
911 EXPECT_CALL(*client, create_surface_done()).Times(1);
912- client->display_server.create_surface(
913- &client->surface_parameters,
914- &client->surface,
915- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::create_surface_done));
916-
917+ client->create_surface();
918 client->wait_for_create_surface();
919
920 EXPECT_CALL(*client, disconnect_done()).Times(1);
921- client->display_server.disconnect(
922- &client->ignored,
923- &client->ignored,
924- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::disconnect_done));
925-
926+ client->disconnect();
927 client->wait_for_disconnect_done();
928
929 Mock::VerifyAndClearExpectations(client.get());
930@@ -247,11 +219,7 @@
931
932 try
933 {
934- client->display_server.disconnect(
935- &client->ignored,
936- &client->ignored,
937- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::disconnect_done));
938-
939+ client->disconnect();
940 // the write beat the socket closing
941 }
942 catch (std::runtime_error const& x)
943@@ -268,11 +236,7 @@
944 EXPECT_CALL(*client, create_surface_done()).Times(testing::AtLeast(0));
945 EXPECT_CALL(*client, disconnect_done()).Times(testing::AtLeast(0));
946
947- client->display_server.create_surface(
948- &client->surface_parameters,
949- &client->surface,
950- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::create_surface_done));
951-
952+ client->create_surface();
953 client->wait_for_create_surface();
954
955 EXPECT_TRUE(client->surface.has_buffer());
956@@ -280,20 +244,12 @@
957
958 for (int i = 0; i != 8; ++i)
959 {
960- client->display_server.next_buffer(
961- &client->surface.id(),
962- client->surface.mutable_buffer(),
963- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::next_buffer_done));
964-
965+ client->next_buffer();
966 client->wait_for_next_buffer();
967 EXPECT_TRUE(client->surface.has_buffer());
968 }
969
970- client->display_server.disconnect(
971- &client->ignored,
972- &client->ignored,
973- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::disconnect_done));
974-
975+ client->disconnect();
976 client->wait_for_disconnect_done();
977 }
978
979@@ -301,19 +257,11 @@
980 connect_create_surface_then_disconnect_a_session)
981 {
982 EXPECT_CALL(*client, create_surface_done()).Times(1);
983- client->display_server.create_surface(
984- &client->surface_parameters,
985- &client->surface,
986- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::create_surface_done));
987-
988+ client->create_surface();
989 client->wait_for_create_surface();
990
991 EXPECT_CALL(*client, disconnect_done()).Times(1);
992- client->display_server.disconnect(
993- &client->ignored,
994- &client->ignored,
995- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::disconnect_done));
996-
997+ client->disconnect();
998 client->wait_for_disconnect_done();
999 }
1000
1001@@ -322,33 +270,22 @@
1002 using namespace testing;
1003
1004 EXPECT_CALL(*client, create_surface_done()).Times(AnyNumber());
1005- client->display_server.create_surface(
1006- &client->surface_parameters,
1007- &client->surface,
1008- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::create_surface_done));
1009-
1010+ client->create_surface();
1011 client->wait_for_create_surface();
1012
1013- std::mutex m;
1014- std::condition_variable cv;
1015- bool done = false;
1016+ mt::WaitCondition wc;
1017
1018- ON_CALL(*communicator_report, error(_)).WillByDefault(Invoke([&] (std::exception const&)
1019+ ON_CALL(*communicator_report, error(_)).WillByDefault(Invoke([&wc] (std::exception const&)
1020 {
1021- std::unique_lock<std::mutex> lock(m);
1022-
1023- done = true;
1024- cv.notify_all();
1025+ wc.wake_up_everyone();
1026 }));
1027
1028 EXPECT_CALL(*communicator_report, error(_)).Times(1);
1029
1030 client.reset();
1031
1032- std::unique_lock<std::mutex> lock(m);
1033-
1034- auto const deadline = std::chrono::steady_clock::now() + std::chrono::seconds(1);
1035- while (!done && cv.wait_until(lock, deadline) != std::cv_status::timeout);
1036+ wc.wait_for_at_most_seconds(1);
1037+ EXPECT_TRUE(wc.woken());
1038 }
1039
1040 TEST_F(PublishedSocketConnector, configure_display)
1041@@ -356,11 +293,7 @@
1042 EXPECT_CALL(*client, display_configure_done())
1043 .Times(1);
1044
1045- client->display_server.configure_display(
1046- &client->disp_config,
1047- &client->disp_config_response,
1048- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::display_configure_done));
1049-
1050+ client->configure_display();
1051 client->wait_for_configure_display_done();
1052 }
1053
1054@@ -373,20 +306,13 @@
1055 client->connect_parameters.set_application_name(__PRETTY_FUNCTION__);
1056
1057 EXPECT_CALL(*client, connect_done()).Times(1);
1058-
1059- client->display_server.connect(
1060- &client->connect_parameters,
1061- &client->connection,
1062- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::connect_done));
1063+ client->connect();
1064+ client->wait_for_connect_done();
1065
1066 EXPECT_CALL(*client, create_surface_done()).Times(testing::AtLeast(0));
1067 EXPECT_CALL(*client, disconnect_done()).Times(testing::AtLeast(0));
1068
1069- client->display_server.create_surface(
1070- &client->surface_parameters,
1071- &client->surface,
1072- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::create_surface_done));
1073-
1074+ client->create_surface();
1075 client->wait_for_create_surface();
1076
1077 EXPECT_TRUE(client->surface.has_buffer());
1078@@ -394,20 +320,12 @@
1079
1080 for (int i = 0; i != next_buffer_calls; ++i)
1081 {
1082- client->display_server.next_buffer(
1083- &client->surface.id(),
1084- client->surface.mutable_buffer(),
1085- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::next_buffer_done));
1086-
1087+ client->next_buffer();
1088 client->wait_for_next_buffer();
1089 EXPECT_TRUE(client->surface.has_buffer());
1090 }
1091
1092- client->display_server.disconnect(
1093- &client->ignored,
1094- &client->ignored,
1095- google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::disconnect_done));
1096-
1097+ client->disconnect();
1098 client->wait_for_disconnect_done();
1099
1100 EXPECT_EQ(__PRETTY_FUNCTION__, stub_server_tool->app_name);
1101
1102=== modified file 'tests/unit-tests/thread/test_basic_thread_pool.cpp'
1103--- tests/unit-tests/thread/test_basic_thread_pool.cpp 2015-06-25 03:00:08 +0000
1104+++ tests/unit-tests/thread/test_basic_thread_pool.cpp 2015-12-14 15:38:49 +0000
1105@@ -22,6 +22,7 @@
1106 #include "mir/test/current_thread_name.h"
1107 #include "mir/test/signal.h"
1108
1109+#include <atomic>
1110 #include <memory>
1111
1112 #include <gmock/gmock.h>
1113@@ -100,7 +101,7 @@
1114 }
1115
1116 private:
1117- bool called;
1118+ std::atomic<bool> called;
1119 bool block;
1120 std::string name;
1121 mt::Signal signal;

Subscribers

People subscribed via source and target branches