Mir

Merge lp:~robert-ancell/mir/pause-status into lp:~mir-team/mir/trunk

Proposed by Robert Ancell
Status: Merged
Approved by: Robert Ancell
Approved revision: no longer in the source branch.
Merged at revision: 1072
Proposed branch: lp:~robert-ancell/mir/pause-status
Merge into: lp:~mir-team/mir/trunk
Diff against target: 380 lines (+245/-0)
8 files modified
include/server/mir/default_pause_resume_listener.h (+40/-0)
include/server/mir/default_server_configuration.h (+2/-0)
include/server/mir/pause_resume_listener.h (+40/-0)
include/server/mir/server_configuration.h (+2/-0)
include/test/mir_test_doubles/mock_pause_resume_listener.h (+44/-0)
src/server/default_server_configuration.cpp (+11/-0)
src/server/display_server.cpp (+7/-0)
tests/integration-tests/test_display_server_main_loop_events.cpp (+99/-0)
To merge this branch: bzr merge lp:~robert-ancell/mir/pause-status
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Alan Griffiths Approve
Review via email: mp+186134@code.launchpad.net

Commit message

Report when paused and resumed via configuration

To post a comment you must log in.
Revision history for this message
Robert Ancell (robert-ancell) wrote :

Required for unity-system-compositor to disable XMir input on VT/session switch: https://code.launchpad.net/~robert-ancell/unity-system-compositor/app-lifecycle/+merge/186135

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
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'm not convinced by the naming: The ServerStatus class doesn't represent a status - it is a listener interface monitoring status transitions. Something like StatusChangeTracker.

It looks as though exceptions have been ignored. What is the correct behavior if, for example "241 + server_status->resumed();" throws. The client code expects a true or false return - not an exception.

What is the connection with the linked bug?

review: Needs Fixing
Revision history for this message
Robert Ancell (robert-ancell) wrote :

Tracker doesn't seem to be used anywhere else in Mir so I think that's a worse name. The "Status" part of the name is weak, since we don't have a concept of what pause() / resume() means. This is the only interface that relates to the server state, I don't see it being transition specific - it could easily be extended to contain get_state().

If the application using libmirserver throws an exception in paused() or removed() I see no reason why we should ignore that - it should stop the server. Also, we're only notifying that the pause/resume has occurred, not controlling it.

The connection to the linked bug is USC needs to know when it has been VT switched away from (i.e. paused) so that it can tell its children to suspend. In the case of XMir this allows it to know when to stop using the input devices

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

> Tracker doesn't seem to be used anywhere else in Mir so I think that's a worse
> name. The "Status" part of the name is weak, since we don't have a concept of
> what pause() / resume() means. This is the only interface that relates to the
> server state, I don't see it being transition specific - it could easily be
> extended to contain get_state().

This interface is used by the display server to notify state transitions - the name ServerState doesn't reflect this role. Does PauseResumeListener sound better to you?

Why would the server want to call get_state()?

> If the application using libmirserver throws an exception in paused() or
> removed() I see no reason why we should ignore that - it should stop the
> server.

It is likely to stop the server in an untidy manner: e.g. it has just restarted all the subsystems and then an exception is thrown that will probably be caught in main().

> Also, we're only notifying that the pause/resume has occurred, not
> controlling it.

So exceptions are, perhaps, not good behaviour?

> The connection to the linked bug is USC needs to know when it has been VT
> switched away from (i.e. paused) so that it can tell its children to suspend.
> In the case of XMir this allows it to know when to stop using the input
> devices

OK

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 :

OK

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Francis Ginther (fginther) wrote :

Amd64 build was hung, re-approving.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'include/server/mir/default_pause_resume_listener.h'
--- include/server/mir/default_pause_resume_listener.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/default_pause_resume_listener.h 2013-09-18 21:09:49 +0000
@@ -0,0 +1,40 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Ancell <robert.ancell@canonical.com>
17 */
18
19#ifndef MIR_DEFAULT_PAUSE_RESUME_LISTENER_H_
20#define MIR_DEFAULT_PAUSE_RESUME_LISTENER_H_
21
22#include "mir/pause_resume_listener.h"
23
24namespace mir
25{
26class DefaultPauseResumeListener : public virtual PauseResumeListener
27{
28public:
29 virtual void paused()
30 {
31 }
32
33 virtual void resumed()
34 {
35 }
36};
37
38}
39
40#endif /* MIR_DEFAULT_PAUSE_RESUME_LISTENER_H_ */
041
=== modified file 'include/server/mir/default_server_configuration.h'
--- include/server/mir/default_server_configuration.h 2013-09-18 16:24:32 +0000
+++ include/server/mir/default_server_configuration.h 2013-09-18 21:09:49 +0000
@@ -123,6 +123,7 @@
123 virtual std::shared_ptr<compositor::Compositor> the_compositor();123 virtual std::shared_ptr<compositor::Compositor> the_compositor();
124 virtual std::shared_ptr<input::InputManager> the_input_manager();124 virtual std::shared_ptr<input::InputManager> the_input_manager();
125 virtual std::shared_ptr<MainLoop> the_main_loop();125 virtual std::shared_ptr<MainLoop> the_main_loop();
126 virtual std::shared_ptr<PauseResumeListener> the_pause_resume_listener();
126 virtual std::shared_ptr<DisplayChanger> the_display_changer();127 virtual std::shared_ptr<DisplayChanger> the_display_changer();
127 virtual std::shared_ptr<graphics::Platform> the_graphics_platform();128 virtual std::shared_ptr<graphics::Platform> the_graphics_platform();
128 virtual std::shared_ptr<input::InputConfiguration> the_input_configuration();129 virtual std::shared_ptr<input::InputConfiguration> the_input_configuration();
@@ -286,6 +287,7 @@
286 CachedPtr<surfaces::SurfaceController> surface_controller;287 CachedPtr<surfaces::SurfaceController> surface_controller;
287 CachedPtr<time::TimeSource> time_source;288 CachedPtr<time::TimeSource> time_source;
288 CachedPtr<MainLoop> main_loop;289 CachedPtr<MainLoop> main_loop;
290 CachedPtr<PauseResumeListener> pause_resume_listener;
289 CachedPtr<graphics::DisplayConfigurationPolicy> display_configuration_policy;291 CachedPtr<graphics::DisplayConfigurationPolicy> display_configuration_policy;
290 CachedPtr<graphics::nested::HostConnection> host_connection;292 CachedPtr<graphics::nested::HostConnection> host_connection;
291 CachedPtr<input::NestedInputRelay> nested_input_relay;293 CachedPtr<input::NestedInputRelay> nested_input_relay;
292294
=== added file 'include/server/mir/pause_resume_listener.h'
--- include/server/mir/pause_resume_listener.h 1970-01-01 00:00:00 +0000
+++ include/server/mir/pause_resume_listener.h 2013-09-18 21:09:49 +0000
@@ -0,0 +1,40 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Ancell <robert.ancell@canonical.com>
17 */
18
19#ifndef MIR_PAUSE_RESUME_LISTENER_H_
20#define MIR_PAUSE_RESUME_LISTENER_H_
21
22namespace mir
23{
24
25class PauseResumeListener
26{
27public:
28 virtual void paused() = 0;
29 virtual void resumed() = 0;
30
31protected:
32 PauseResumeListener() = default;
33 virtual ~PauseResumeListener() = default;
34 PauseResumeListener(PauseResumeListener const&) = delete;
35 PauseResumeListener& operator=(PauseResumeListener const&) = delete;
36};
37
38}
39
40#endif /* MIR_PAUSE_RESUME_LISTENER_H_ */
041
=== modified file 'include/server/mir/server_configuration.h'
--- include/server/mir/server_configuration.h 2013-08-28 03:41:48 +0000
+++ include/server/mir/server_configuration.h 2013-09-18 21:09:49 +0000
@@ -49,6 +49,7 @@
49}49}
5050
51class MainLoop;51class MainLoop;
52class PauseResumeListener;
52class DisplayChanger;53class DisplayChanger;
5354
54class ServerConfiguration55class ServerConfiguration
@@ -61,6 +62,7 @@
61 virtual std::shared_ptr<compositor::Compositor> the_compositor() = 0;62 virtual std::shared_ptr<compositor::Compositor> the_compositor() = 0;
62 virtual std::shared_ptr<input::InputManager> the_input_manager() = 0;63 virtual std::shared_ptr<input::InputManager> the_input_manager() = 0;
63 virtual std::shared_ptr<MainLoop> the_main_loop() = 0;64 virtual std::shared_ptr<MainLoop> the_main_loop() = 0;
65 virtual std::shared_ptr<PauseResumeListener> the_pause_resume_listener() = 0;
64 virtual std::shared_ptr<DisplayChanger> the_display_changer() = 0;66 virtual std::shared_ptr<DisplayChanger> the_display_changer() = 0;
65 virtual std::shared_ptr<graphics::Platform> the_graphics_platform() = 0;67 virtual std::shared_ptr<graphics::Platform> the_graphics_platform() = 0;
66 virtual std::shared_ptr<input::InputConfiguration> the_input_configuration() = 0;68 virtual std::shared_ptr<input::InputConfiguration> the_input_configuration() = 0;
6769
=== added file 'include/test/mir_test_doubles/mock_pause_resume_listener.h'
--- include/test/mir_test_doubles/mock_pause_resume_listener.h 1970-01-01 00:00:00 +0000
+++ include/test/mir_test_doubles/mock_pause_resume_listener.h 2013-09-18 21:09:49 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright © 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Robert Ancell <robert.ancell@canonical.com>
17 */
18
19#ifndef MIR_TEST_DOUBLES_MOCK_PAUSE_RESUME_LISTENER_H_
20#define MIR_TEST_DOUBLES_MOCK_PAUSE_RESUME_LISTENER_H_
21
22#include "mir/pause_resume_listener.h"
23
24#include <gmock/gmock.h>
25
26namespace mir
27{
28namespace test
29{
30namespace doubles
31{
32
33class MockPauseResumeListener : public mir::PauseResumeListener
34{
35public:
36 MOCK_METHOD0(paused, void());
37 MOCK_METHOD0(resumed, void());
38};
39
40}
41}
42}
43
44#endif /* MIR_TEST_DOUBLES_MOCK_PAUSE_RESUME_LISTENER_H_ */
045
=== modified file 'src/server/default_server_configuration.cpp'
--- src/server/default_server_configuration.cpp 2013-09-18 16:24:32 +0000
+++ src/server/default_server_configuration.cpp 2013-09-18 21:09:49 +0000
@@ -19,6 +19,7 @@
19#include "mir/default_server_configuration.h"19#include "mir/default_server_configuration.h"
20#include "mir/abnormal_exit.h"20#include "mir/abnormal_exit.h"
21#include "mir/asio_main_loop.h"21#include "mir/asio_main_loop.h"
22#include "mir/default_pause_resume_listener.h"
22#include "mir/shared_library.h"23#include "mir/shared_library.h"
2324
24#include "mir/options/program_option.h"25#include "mir/options/program_option.h"
@@ -936,6 +937,16 @@
936 });937 });
937}938}
938939
940
941std::shared_ptr<mir::PauseResumeListener> mir::DefaultServerConfiguration::the_pause_resume_listener()
942{
943 return pause_resume_listener(
944 []()
945 {
946 return std::make_shared<mir::DefaultPauseResumeListener>();
947 });
948}
949
939std::shared_ptr<mg::DisplayConfigurationPolicy>950std::shared_ptr<mg::DisplayConfigurationPolicy>
940mir::DefaultServerConfiguration::the_display_configuration_policy()951mir::DefaultServerConfiguration::the_display_configuration_policy()
941{952{
942953
=== modified file 'src/server/display_server.cpp'
--- src/server/display_server.cpp 2013-08-28 03:41:48 +0000
+++ src/server/display_server.cpp 2013-09-18 21:09:49 +0000
@@ -21,6 +21,7 @@
21#include "mir/display_server.h"21#include "mir/display_server.h"
22#include "mir/server_configuration.h"22#include "mir/server_configuration.h"
23#include "mir/main_loop.h"23#include "mir/main_loop.h"
24#include "mir/pause_resume_listener.h"
24#include "mir/display_changer.h"25#include "mir/display_changer.h"
2526
26#include "mir/compositor/compositor.h"27#include "mir/compositor/compositor.h"
@@ -74,6 +75,7 @@
74 communicator{config.the_communicator()},75 communicator{config.the_communicator()},
75 input_manager{config.the_input_manager()},76 input_manager{config.the_input_manager()},
76 main_loop{config.the_main_loop()},77 main_loop{config.the_main_loop()},
78 pause_resume_listener{config.the_pause_resume_listener()},
77 display_changer{config.the_display_changer()},79 display_changer{config.the_display_changer()},
78 paused{false},80 paused{false},
79 configure_display_on_resume{false}81 configure_display_on_resume{false}
@@ -113,6 +115,8 @@
113 return false;115 return false;
114 }116 }
115117
118 pause_resume_listener->paused();
119
116 return true;120 return true;
117 }121 }
118122
@@ -149,6 +153,8 @@
149 return false;153 return false;
150 }154 }
151155
156 pause_resume_listener->resumed();
157
152 return true;158 return true;
153 }159 }
154160
@@ -173,6 +179,7 @@
173 std::shared_ptr<mf::Communicator> const communicator;179 std::shared_ptr<mf::Communicator> const communicator;
174 std::shared_ptr<mi::InputManager> const input_manager;180 std::shared_ptr<mi::InputManager> const input_manager;
175 std::shared_ptr<mir::MainLoop> const main_loop;181 std::shared_ptr<mir::MainLoop> const main_loop;
182 std::shared_ptr<mir::PauseResumeListener> const pause_resume_listener;
176 std::shared_ptr<mir::DisplayChanger> const display_changer;183 std::shared_ptr<mir::DisplayChanger> const display_changer;
177 bool paused;184 bool paused;
178 bool configure_display_on_resume;185 bool configure_display_on_resume;
179186
=== modified file 'tests/integration-tests/test_display_server_main_loop_events.cpp'
--- tests/integration-tests/test_display_server_main_loop_events.cpp 2013-08-28 03:41:48 +0000
+++ tests/integration-tests/test_display_server_main_loop_events.cpp 2013-09-18 21:09:49 +0000
@@ -22,12 +22,14 @@
22#include "mir/graphics/display_configuration_policy.h"22#include "mir/graphics/display_configuration_policy.h"
23#include "mir/main_loop.h"23#include "mir/main_loop.h"
24#include "mir/display_changer.h"24#include "mir/display_changer.h"
25#include "mir/pause_resume_listener.h"
2526
26#include "mir_test/pipe.h"27#include "mir_test/pipe.h"
27#include "mir_test_framework/testing_server_configuration.h"28#include "mir_test_framework/testing_server_configuration.h"
28#include "mir_test_doubles/mock_input_manager.h"29#include "mir_test_doubles/mock_input_manager.h"
29#include "mir_test_doubles/mock_compositor.h"30#include "mir_test_doubles/mock_compositor.h"
30#include "mir_test_doubles/null_display.h"31#include "mir_test_doubles/null_display.h"
32#include "mir_test_doubles/mock_pause_resume_listener.h"
31#include "mir/run_mir.h"33#include "mir/run_mir.h"
3234
33#include <gtest/gtest.h>35#include <gtest/gtest.h>
@@ -311,6 +313,71 @@
311 int const resume_signal;313 int const resume_signal;
312};314};
313315
316class TestPauseResumeListenerConfig : public mtf::TestingServerConfiguration
317{
318public:
319 TestPauseResumeListenerConfig()
320 : pause_signal{SIGUSR1}, resume_signal{SIGUSR2}
321 {
322 }
323
324 std::shared_ptr<mg::Display> the_display() override
325 {
326 if (!mock_display)
327 {
328 auto display = mtf::TestingServerConfiguration::the_display();
329 mock_display = std::make_shared<MockDisplay>(display,
330 pause_signal,
331 resume_signal,
332 p.read_fd());
333 }
334
335 return mock_display;
336 }
337
338 std::shared_ptr<mir::PauseResumeListener> the_pause_resume_listener() override
339 {
340 if (!mock_pause_resume_listener)
341 mock_pause_resume_listener = std::make_shared<mtd::MockPauseResumeListener>();
342
343 return mock_pause_resume_listener;
344 }
345
346 std::shared_ptr<MockDisplay> the_mock_display()
347 {
348 the_display();
349 return mock_display;
350 }
351
352 std::shared_ptr<mtd::MockPauseResumeListener> the_mock_pause_resume_listener()
353 {
354 the_pause_resume_listener();
355 return mock_pause_resume_listener;
356 }
357
358 void emit_pause_event_and_wait_for_handler()
359 {
360 kill(getpid(), pause_signal);
361 while (!mock_display->pause_handler_invoked())
362 std::this_thread::sleep_for(std::chrono::microseconds{500});
363 }
364
365 void emit_resume_event_and_wait_for_handler()
366 {
367 kill(getpid(), resume_signal);
368 while (!mock_display->resume_handler_invoked())
369 std::this_thread::sleep_for(std::chrono::microseconds{500});
370 }
371
372private:
373 std::shared_ptr<MockDisplay> mock_display;
374 std::shared_ptr<mtd::MockPauseResumeListener> mock_pause_resume_listener;
375
376 mt::Pipe p;
377 int const pause_signal;
378 int const resume_signal;
379};
380
314}381}
315382
316TEST(DisplayServerMainLoopEvents, display_server_shuts_down_properly_on_sigint)383TEST(DisplayServerMainLoopEvents, display_server_shuts_down_properly_on_sigint)
@@ -582,3 +649,35 @@
582 t.detach();649 t.detach();
583 });650 });
584}651}
652
653TEST(DisplayServerMainLoopEvents, pause_resume_listener)
654{
655 using namespace testing;
656
657 TestPauseResumeListenerConfig server_config;
658
659 auto mock_display = server_config.the_mock_display();
660 auto mock_pause_resume_listener = server_config.the_mock_pause_resume_listener();
661
662 {
663 InSequence s;
664
665 EXPECT_CALL(*mock_display, pause()).Times(1);
666 EXPECT_CALL(*mock_pause_resume_listener, paused()).Times(1);
667 EXPECT_CALL(*mock_display, resume()).Times(1);
668 EXPECT_CALL(*mock_pause_resume_listener, resumed()).Times(1);
669 }
670
671 mir::run_mir(server_config,
672 [&server_config](mir::DisplayServer&)
673 {
674 std::thread t{
675 [&]
676 {
677 server_config.emit_pause_event_and_wait_for_handler();
678 server_config.emit_resume_event_and_wait_for_handler();
679 kill(getpid(), SIGTERM);
680 }};
681 t.detach();
682 });
683}

Subscribers

People subscribed via source and target branches