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