diff -Nru mir-0.24.1+16.10.20160927/debian/changelog mir-0.24.1+16.10.20160928/debian/changelog --- mir-0.24.1+16.10.20160927/debian/changelog 2016-09-28 12:12:20.000000000 +0000 +++ mir-0.24.1+16.10.20160928/debian/changelog 2016-09-28 12:12:21.000000000 +0000 @@ -1,4 +1,4 @@ -mir (0.24.1+16.10.20160927-0ubuntu1) yakkety; urgency=medium +mir (0.24.1+16.10.20160928-0ubuntu1) yakkety; urgency=medium * New upstream release 0.24.1 (https://launchpad.net/mir/+milestone/0.24.1) - ABI summary: @@ -9,8 +9,14 @@ is configured (LP: #1626435) . fix for libmircommon.so.6 ABI break: version stanza of mir::dispatch::ReadableFd* moved to newer version (LP: #1617865) + . clang builds fail (again) (LP: #1609612) + . Valgrind errors in NesterServer.* cause subsequent tests + (ServerDisconnect, ServerStartup, UnresponsiveClient) to fail + (LP: #1612012) + . Break potentially infinite loop in search for next session to focus + (LP: #1625401) - -- Andreas Pokorny Tue, 27 Sep 2016 09:22:53 +0000 + -- Andreas Pokorny Wed, 28 Sep 2016 12:09:49 +0000 mir (0.24.0+16.10.20160815.3-0ubuntu1) yakkety; urgency=medium diff -Nru mir-0.24.1+16.10.20160927/src/client/buffer_factory.cpp mir-0.24.1+16.10.20160928/src/client/buffer_factory.cpp --- mir-0.24.1+16.10.20160927/src/client/buffer_factory.cpp 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/src/client/buffer_factory.cpp 2016-09-28 12:09:29.000000000 +0000 @@ -86,7 +86,7 @@ } allocation_requests.erase(request_it); - return std::move(b); + return b; } void mcl::BufferFactory::cancel_requests_with_context(void* cancelled_context) diff -Nru mir-0.24.1+16.10.20160927/src/client/rpc/mir_protobuf_rpc_channel.cpp mir-0.24.1+16.10.20160928/src/client/rpc/mir_protobuf_rpc_channel.cpp --- mir-0.24.1+16.10.20160927/src/client/rpc/mir_protobuf_rpc_channel.cpp 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/src/client/rpc/mir_protobuf_rpc_channel.cpp 2016-09-28 12:09:29.000000000 +0000 @@ -52,11 +52,6 @@ namespace md = mir::dispatch; namespace mp = mir::protobuf; -namespace -{ -std::chrono::milliseconds const timeout(200); -} - mclr::MirProtobufRpcChannel::MirProtobufRpcChannel( std::unique_ptr transport, std::shared_ptr const& surface_map, diff -Nru mir-0.24.1+16.10.20160927/src/platforms/eglstream-kms/client/client_platform.cpp mir-0.24.1+16.10.20160928/src/platforms/eglstream-kms/client/client_platform.cpp --- mir-0.24.1+16.10.20160927/src/platforms/eglstream-kms/client/client_platform.cpp 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/src/platforms/eglstream-kms/client/client_platform.cpp 2016-09-28 12:09:29.000000000 +0000 @@ -29,8 +29,7 @@ namespace mcle=mir::client::eglstream; namespace geom=mir::geometry; -mcle::ClientPlatform::ClientPlatform(ClientContext* const context) - : context{context} +mcle::ClientPlatform::ClientPlatform(ClientContext* const) { } diff -Nru mir-0.24.1+16.10.20160927/src/platforms/eglstream-kms/client/client_platform.h mir-0.24.1+16.10.20160928/src/platforms/eglstream-kms/client/client_platform.h --- mir-0.24.1+16.10.20160927/src/platforms/eglstream-kms/client/client_platform.h 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/src/platforms/eglstream-kms/client/client_platform.h 2016-09-28 12:09:29.000000000 +0000 @@ -30,7 +30,7 @@ class ClientPlatform : public client::ClientPlatform { public: - ClientPlatform(ClientContext* const context); + ClientPlatform(ClientContext* const); MirPlatformType platform_type() const override; void populate(MirPlatformPackage& package) const override; @@ -40,9 +40,6 @@ std::shared_ptr create_egl_native_display() override; MirNativeBuffer* convert_native_buffer(graphics::NativeBuffer*) const override; MirPixelFormat get_egl_pixel_format(EGLDisplay, EGLConfig) const override; - -private: - ClientContext* const context; }; } diff -Nru mir-0.24.1+16.10.20160927/src/platforms/eglstream-kms/server/platform.cpp mir-0.24.1+16.10.20160928/src/platforms/eglstream-kms/server/platform.cpp --- mir-0.24.1+16.10.20160927/src/platforms/eglstream-kms/server/platform.cpp 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/src/platforms/eglstream-kms/server/platform.cpp 2016-09-28 12:09:29.000000000 +0000 @@ -55,8 +55,7 @@ EGLDeviceEXT device, std::shared_ptr const& /*emergency_cleanup_registry*/, std::shared_ptr const& /*report*/) - : device{device}, - display{EGL_NO_DISPLAY}, + : display{EGL_NO_DISPLAY}, drm_node{open(drm_node_for_device(device), O_RDWR | O_CLOEXEC)} { using namespace std::literals; diff -Nru mir-0.24.1+16.10.20160927/src/platforms/eglstream-kms/server/platform.h mir-0.24.1+16.10.20160928/src/platforms/eglstream-kms/server/platform.h --- mir-0.24.1+16.10.20160927/src/platforms/eglstream-kms/server/platform.h 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/src/platforms/eglstream-kms/server/platform.h 2016-09-28 12:09:29.000000000 +0000 @@ -53,7 +53,6 @@ UniqueModulePtr make_ipc_operations() const override; private: - EGLDeviceEXT device; EGLDisplay display; mir::Fd const drm_node; }; diff -Nru mir-0.24.1+16.10.20160927/src/server/graphics/nested/display_buffer.cpp mir-0.24.1+16.10.20160928/src/server/graphics/nested/display_buffer.cpp --- mir-0.24.1+16.10.20160927/src/server/graphics/nested/display_buffer.cpp 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/src/server/graphics/nested/display_buffer.cpp 2016-09-28 12:09:29.000000000 +0000 @@ -93,6 +93,7 @@ mgn::detail::DisplayBuffer::~DisplayBuffer() noexcept { + host_surface->set_event_handler(nullptr, nullptr); } void mgn::detail::DisplayBuffer::event_thunk( diff -Nru mir-0.24.1+16.10.20160927/src/server/shell/abstract_shell.cpp mir-0.24.1+16.10.20160928/src/server/shell/abstract_shell.cpp --- mir-0.24.1+16.10.20160927/src/server/shell/abstract_shell.cpp 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/src/server/shell/abstract_shell.cpp 2016-09-28 12:09:29.000000000 +0000 @@ -193,12 +193,14 @@ std::unique_lock lock(focus_mutex); auto const focused_session = focus_session.lock(); auto successor = session_coordinator->successor_of(focused_session); + auto const sentinel = successor; while (successor != nullptr && - successor != focused_session && successor->default_surface() == nullptr) { successor = session_coordinator->successor_of(successor); + if (successor == sentinel) + break; } auto const surface = successor ? successor->default_surface() : nullptr; diff -Nru mir-0.24.1+16.10.20160927/tests/unit-tests/graphics/mesa/test_ipc_operations.cpp mir-0.24.1+16.10.20160928/tests/unit-tests/graphics/mesa/test_ipc_operations.cpp --- mir-0.24.1+16.10.20160927/tests/unit-tests/graphics/mesa/test_ipc_operations.cpp 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/tests/unit-tests/graphics/mesa/test_ipc_operations.cpp 2016-09-28 12:09:29.000000000 +0000 @@ -84,7 +84,11 @@ EXPECT_CALL(mock_buffer_msg, pack_fd(mtd::RawFdMatcher(native_handle.fd[i]))); for(auto i = 0; i < native_handle.data_items; i++) EXPECT_CALL(mock_buffer_msg, pack_data(native_handle.data[i])); +#ifndef __clang__ + // FIXME: Why can't clang compile this on yakkety (with the + // gcc6 headers)? (LP: #1609612) EXPECT_CALL(mock_buffer_msg, pack_stride(dummy_stride)); +#endif EXPECT_CALL(mock_buffer_msg, pack_flags(testing::_)); EXPECT_CALL(mock_buffer_msg, pack_size(dummy_size)); diff -Nru mir-0.24.1+16.10.20160927/tests/unit-tests/graphics/nested/CMakeLists.txt mir-0.24.1+16.10.20160928/tests/unit-tests/graphics/nested/CMakeLists.txt --- mir-0.24.1+16.10.20160927/tests/unit-tests/graphics/nested/CMakeLists.txt 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/tests/unit-tests/graphics/nested/CMakeLists.txt 2016-09-28 12:09:29.000000000 +0000 @@ -1,6 +1,7 @@ list(APPEND UNIT_TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test_nested_display_configuration.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_nested_display.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_nested_display_buffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mir_display_configuration_builder.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_nested_cursor.cpp ) diff -Nru mir-0.24.1+16.10.20160927/tests/unit-tests/graphics/nested/test_nested_display_buffer.cpp mir-0.24.1+16.10.20160928/tests/unit-tests/graphics/nested/test_nested_display_buffer.cpp --- mir-0.24.1+16.10.20160927/tests/unit-tests/graphics/nested/test_nested_display_buffer.cpp 1970-01-01 00:00:00.000000000 +0000 +++ mir-0.24.1+16.10.20160928/tests/unit-tests/graphics/nested/test_nested_display_buffer.cpp 2016-09-28 12:09:29.000000000 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright © 2016 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authored by: Alexandros Frantzis + */ + +#include "src/server/graphics/nested/display_buffer.h" + +#include "mir/events/event_builders.h" + +#include "mir/test/doubles/mock_egl.h" +#include "mir/test/doubles/stub_gl_config.h" +#include "mir/test/doubles/stub_host_connection.h" +#include "mir/test/fake_shared.h" + +#include +#include + +namespace mgn = mir::graphics::nested; +namespace mgnd = mgn::detail; +namespace mt = mir::test; +namespace mtd = mir::test::doubles; + +namespace +{ + +class EventHostSurface : public mgn::HostSurface +{ +public: + EGLNativeWindowType egl_native_window() override { return {}; } + + void set_event_handler(mir_surface_event_callback cb, void* ctx) override + { + std::lock_guard lock{event_mutex}; + event_handler = cb; + event_context = ctx; + } + + void emit_input_event() + { + auto const ev = mir::events::make_event( + MirInputDeviceId(), {}, std::vector{}, + MirKeyboardAction(), 0, 0, MirInputEventModifiers()); + + std::lock_guard lock{event_mutex}; + // Normally we shouldn't call external code under lock, but, for our + // test use case, doing so is safe and simplifies the test code. + if (event_handler) + event_handler(nullptr, ev.get(), event_context); + } + +private: + std::mutex event_mutex; + mir_surface_event_callback event_handler; + void* event_context; +}; + +struct NestedDisplayBuffer : testing::Test +{ + auto create_display_buffer() + { + return std::make_shared( + egl_display, + mt::fake_shared(host_surface), + mir::geometry::Rectangle{}, + MirPixelFormat{}, + std::make_shared() + ); + } + + testing::NiceMock mock_egl; + mgnd::EGLDisplayHandle egl_display{nullptr, std::make_shared()}; + EventHostSurface host_surface; +}; + +} + +// Regression test for LP: #1612012 +// This test is trying to reproduce a race, so it's not deterministic, but +// in practice the reproduction rate is very close to 100%. +TEST_F(NestedDisplayBuffer, event_dispatch_does_not_race_with_destruction) +{ + auto display_buffer = create_display_buffer(); + std::thread t{ + [&] + { + for (int i = 0; i < 100; ++i) + host_surface.emit_input_event(); + }}; + + display_buffer.reset(); + t.join(); +} diff -Nru mir-0.24.1+16.10.20160927/tests/unit-tests/scene/test_abstract_shell.cpp mir-0.24.1+16.10.20160928/tests/unit-tests/scene/test_abstract_shell.cpp --- mir-0.24.1+16.10.20160927/tests/unit-tests/scene/test_abstract_shell.cpp 2016-09-27 09:22:13.000000000 +0000 +++ mir-0.24.1+16.10.20160928/tests/unit-tests/scene/test_abstract_shell.cpp 2016-09-28 12:09:29.000000000 +0000 @@ -544,9 +544,9 @@ session->destroy_surface(surface_id); EXPECT_CALL(session_container, successor_of(session)). - WillOnce(Return(session1)); + WillRepeatedly(Return(session1)); EXPECT_CALL(session_container, successor_of(session1)). - WillOnce(Return(session)); + WillRepeatedly(Return(session)); EXPECT_CALL(session_event_sink, handle_no_focus()); @@ -589,6 +589,30 @@ shell.modify_surface(session, surface, stream_modification); } +// lp:1625401 +TEST_F(AbstractShell, when_remaining_session_has_no_surface_focus_next_session_doesnt_loop_endlessly) +{ + std::shared_ptr empty_session = + shell.open_session(__LINE__, "empty_session", std::shared_ptr()); + + { + std::shared_ptr another_session = + shell.open_session(__LINE__, "another_session", std::shared_ptr()); + + auto creation_params = ms::a_surface() + .with_buffer_stream(another_session->create_buffer_stream(properties)); + auto surface_id = shell.create_surface(another_session, creation_params, nullptr); + + shell.set_focus_to(another_session, another_session->surface(surface_id)); + + shell.close_session(another_session); + } + + ON_CALL(session_container, successor_of(_)).WillByDefault(Return(empty_session)); + + shell.focus_next_session(); +} + namespace mir { namespace scene