Merge lp:~alan-griffiths/qtmir/new-migrate-to-mir-Server-API into lp:qtmir

Proposed by Alan Griffiths
Status: Merged
Approved by: Gerry Boland
Approved revision: 290
Merged at revision: 291
Proposed branch: lp:~alan-griffiths/qtmir/new-migrate-to-mir-Server-API
Merge into: lp:qtmir
Diff against target: 489 lines (+128/-139)
10 files modified
src/platforms/mirserver/display.cpp (+1/-1)
src/platforms/mirserver/display.h (+3/-3)
src/platforms/mirserver/miropenglcontext.cpp (+1/-1)
src/platforms/mirserver/miropenglcontext.h (+3/-3)
src/platforms/mirserver/mirserverconfiguration.cpp (+40/-77)
src/platforms/mirserver/mirserverconfiguration.h (+4/-14)
src/platforms/mirserver/mirserverintegration.cpp (+0/-12)
src/platforms/mirserver/qmirserver.cpp (+34/-0)
src/platforms/mirserver/qmirserver.h (+17/-8)
tests/modules/common/qtmir_test.h (+25/-20)
To merge this branch: bzr merge lp:~alan-griffiths/qtmir/new-migrate-to-mir-Server-API
Reviewer Review Type Date Requested Status
Gerry Boland (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+243177@code.launchpad.net

Commit message

Migration of qtmir from the legacy Mir API

Description of the change

Migration of qtmir from the legacy Mir API

This is somewhat minimalist - there's possibilities of code cleanup and improved naming. But it moves the dependencies over to the mir::Server based APIs and seems to run OK on krillin/15.04(r39).

I'll look at the cleanup work next week.

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

 * Are there any related MPs required for this MP to build/function as expected? Please list.
N
 * Did you perform an exploratory manual test run of your code change and any related functionality?
Y
 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
N/A

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
289. By Alan Griffiths

Fix initialization order in tests

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

I approve of the code-changes, but testing on a desktop machine, it crashes on startup: http://pastebin.ubuntu.com/9332816/

review: Needs Fixing
Revision history for this message
Gerry Boland (gerboland) wrote :

For more info, I just checked out this branch on my vivid machine, built it, installed it, and tried to log into a unity8 desktop session. The backtrace was what I managed to get manually, may not be actual issue.

290. By Alan Griffiths

Fix startup race condition

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 :

Also tested on with desktop U8

Revision history for this message
Gerry Boland (gerboland) wrote :

Yep, working nicely now, thanks

 * Did you perform an exploratory manual test run of the code change and any related functionality?
Y
 * Did CI run pass? If not, please explain why.
Y

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/platforms/mirserver/display.cpp'
2--- src/platforms/mirserver/display.cpp 2014-10-16 18:27:04 +0000
3+++ src/platforms/mirserver/display.cpp 2014-12-02 12:30:45 +0000
4@@ -27,7 +27,7 @@
5
6 // TODO: Listen for display changes and update the list accordingly
7
8-Display::Display(const QSharedPointer<mir::DefaultServerConfiguration> &config, QObject *parent)
9+Display::Display(const QSharedPointer<mir::Server> &config, QObject *parent)
10 : QObject(parent)
11 , m_mirConfig(config)
12 {
13
14=== modified file 'src/platforms/mirserver/display.h'
15--- src/platforms/mirserver/display.h 2014-10-10 18:52:44 +0000
16+++ src/platforms/mirserver/display.h 2014-12-02 12:30:45 +0000
17@@ -23,20 +23,20 @@
18 #include <qpa/qplatformscreen.h>
19
20 #include "mir/graphics/display.h"
21-#include "mir/default_server_configuration.h"
22+#include "mir/server.h"
23
24 class Display : public QObject
25 {
26 Q_OBJECT
27 public:
28- Display(const QSharedPointer<mir::DefaultServerConfiguration> &config, QObject *parent = 0);
29+ Display(const QSharedPointer<mir::Server> &config, QObject *parent = 0);
30 ~Display();
31
32 QList<QPlatformScreen *> screens() const { return m_screens; }
33
34 private:
35 QList<QPlatformScreen *> m_screens;
36- const QSharedPointer<mir::DefaultServerConfiguration> m_mirConfig;
37+ const QSharedPointer<mir::Server> m_mirConfig;
38 };
39
40 #endif // DISPLAY_H
41
42=== modified file 'src/platforms/mirserver/miropenglcontext.cpp'
43--- src/platforms/mirserver/miropenglcontext.cpp 2014-07-15 11:30:11 +0000
44+++ src/platforms/mirserver/miropenglcontext.cpp 2014-12-02 12:30:45 +0000
45@@ -35,7 +35,7 @@
46 // The Mir "Display" generates a shared GL context for all DisplayBuffers
47 // (i.e. individual display output buffers) to use as a common base context.
48
49-MirOpenGLContext::MirOpenGLContext(const QSharedPointer<mir::DefaultServerConfiguration> &config, const QSurfaceFormat &format)
50+MirOpenGLContext::MirOpenGLContext(const QSharedPointer<mir::Server> &config, const QSurfaceFormat &format)
51 : m_mirConfig(config)
52 #if GL_DEBUG
53 , m_logger(new QOpenGLDebugLogger(this))
54
55=== modified file 'src/platforms/mirserver/miropenglcontext.h'
56--- src/platforms/mirserver/miropenglcontext.h 2014-05-16 16:45:00 +0000
57+++ src/platforms/mirserver/miropenglcontext.h 2014-12-02 12:30:45 +0000
58@@ -27,13 +27,13 @@
59 #include <QOpenGLDebugLogger>
60 #endif
61
62-#include <mir/default_server_configuration.h>
63+#include <mir/server.h>
64
65 class MirOpenGLContext : public QObject, public QPlatformOpenGLContext
66 {
67 Q_OBJECT
68 public:
69- MirOpenGLContext(const QSharedPointer<mir::DefaultServerConfiguration> &, const QSurfaceFormat &);
70+ MirOpenGLContext(const QSharedPointer<mir::Server> &, const QSurfaceFormat &);
71 ~MirOpenGLContext() = default;
72
73 QSurfaceFormat format() const override;
74@@ -52,7 +52,7 @@
75 #endif
76
77 private:
78- const QSharedPointer<mir::DefaultServerConfiguration> m_mirConfig;
79+ const QSharedPointer<mir::Server> m_mirConfig;
80 QSurfaceFormat m_format;
81 #if GL_DEBUG
82 QOpenGLDebugLogger *m_logger;
83
84=== modified file 'src/platforms/mirserver/mirserverconfiguration.cpp'
85--- src/platforms/mirserver/mirserverconfiguration.cpp 2014-09-17 12:48:54 +0000
86+++ src/platforms/mirserver/mirserverconfiguration.cpp 2014-12-02 12:30:45 +0000
87@@ -14,6 +14,8 @@
88 * along with this program. If not, see <http://www.gnu.org/licenses/>.
89 */
90
91+#include <QCoreApplication>
92+
93 #include "mirserverconfiguration.h"
94
95 // local
96@@ -50,115 +52,76 @@
97
98 MirServerConfiguration::MirServerConfiguration(int argc, char const* argv[], QObject* parent)
99 : QObject(parent)
100- , DefaultServerConfiguration(std::make_shared<mo::DefaultConfiguration>(argc, argv, &ignore_unparsed_arguments))
101 {
102- qCDebug(QTMIR_MIR_MESSAGES) << "MirServerConfiguration created";
103-}
104+ set_command_line_handler(&ignore_unparsed_arguments);
105+ set_command_line(argc, argv);
106
107-std::shared_ptr<ms::PlacementStrategy>
108-MirServerConfiguration::the_placement_strategy()
109-{
110- return shell_placement_strategy(
111- [this]
112+ override_the_placement_strategy([this]
113 {
114 return std::make_shared<MirPlacementStrategy>(the_shell_display_layout());
115 });
116-}
117
118-std::shared_ptr<ms::SessionListener>
119-MirServerConfiguration::the_session_listener()
120-{
121- return session_listener(
122- [this]
123+ override_the_session_listener([]
124 {
125 return std::make_shared<SessionListener>();
126 });
127-}
128
129-std::shared_ptr<ms::PromptSessionListener>
130-MirServerConfiguration::the_prompt_session_listener()
131-{
132- return prompt_session_listener(
133- [this]
134+ override_the_prompt_session_listener([]
135 {
136 return std::make_shared<PromptSessionListener>();
137 });
138-}
139
140-std::shared_ptr<ms::SurfaceConfigurator>
141-MirServerConfiguration::the_surface_configurator()
142-{
143- return surface_configurator(
144- [this]()
145+ override_the_surface_configurator([]
146 {
147 return std::make_shared<SurfaceConfigurator>();
148 });
149-}
150-
151-std::shared_ptr<mir::frontend::SessionAuthorizer>
152-MirServerConfiguration::the_session_authorizer()
153-{
154- return session_authorizer(
155- []
156- {
157- return std::make_shared<SessionAuthorizer>();
158- });
159-}
160-
161-std::shared_ptr<mir::compositor::Compositor>
162-MirServerConfiguration::the_compositor()
163-{
164- return compositor(
165- [this]()
166+
167+ override_the_session_authorizer([]
168+ {
169+ return std::make_shared<SessionAuthorizer>();
170+ });
171+
172+ override_the_compositor([]
173 {
174 return std::make_shared<QtCompositor>();
175 });
176-}
177-
178-std::shared_ptr<mir::input::InputDispatcher>
179-MirServerConfiguration::the_input_dispatcher()
180-{
181- return input_dispatcher(
182- [this]()
183- {
184- return std::make_shared<QtEventFeeder>();
185- });
186-}
187-
188-std::shared_ptr<mir::graphics::GLConfig>
189-MirServerConfiguration::the_gl_config()
190-{
191- return gl_config(
192- [this]()
193- {
194+
195+ override_the_input_dispatcher([]
196+ {
197+ return std::make_shared<QtEventFeeder>();
198+ });
199+
200+ override_the_gl_config([]
201+ {
202 #ifdef QTMIR_USE_OPENGL
203- // Should desktop-GL be desired, need to bind that API before a context is created
204- eglBindAPI(EGL_OPENGL_API);
205+ // Should desktop-GL be desired, need to bind that API before a context is created
206+ eglBindAPI(EGL_OPENGL_API);
207 #endif
208- return std::make_shared<MirGLConfig>();
209- });
210-}
211+ return std::make_shared<MirGLConfig>();
212+ });
213
214-std::shared_ptr<mir::ServerStatusListener>
215-MirServerConfiguration::the_server_status_listener()
216-{
217- return server_status_listener(
218- []()
219+ override_the_server_status_listener([]
220 {
221 return std::make_shared<MirServerStatusListener>();
222 });
223-}
224
225-std::shared_ptr<mir::shell::FocusSetter>
226-MirServerConfiguration::the_shell_focus_setter()
227-{
228- return shell_focus_setter(
229- [this]
230+ override_the_shell_focus_setter([]
231 {
232 return std::make_shared<FocusSetter>();
233 });
234+
235+ set_terminator([&](int)
236+ {
237+ qDebug() << "Signal caught by Mir, stopping Mir server..";
238+ QCoreApplication::quit();
239+ });
240+
241+ apply_settings();
242+
243+ qCDebug(QTMIR_MIR_MESSAGES) << "MirServerConfiguration created";
244 }
245
246+
247 /************************************ Shell side ************************************/
248
249 //
250
251=== modified file 'src/platforms/mirserver/mirserverconfiguration.h'
252--- src/platforms/mirserver/mirserverconfiguration.h 2014-09-17 12:34:40 +0000
253+++ src/platforms/mirserver/mirserverconfiguration.h 2014-12-02 12:30:45 +0000
254@@ -18,7 +18,7 @@
255 #define MIRSERVERCONFIGURATION_H
256
257 #include <QObject>
258-#include <mir/default_server_configuration.h>
259+#include <mir/server.h>
260
261 class QtEventFeeder;
262 class SessionListener;
263@@ -26,7 +26,9 @@
264 class SurfaceConfigurator;
265 class PromptSessionListener;
266
267-class MirServerConfiguration : public QObject, public mir::DefaultServerConfiguration
268+// We use virtual inheritance of mir::Server to facilitate derived classes (e.g. testing)
269+// calling initialization functions before MirServerConfiguration is constructed.
270+class MirServerConfiguration : public QObject, public virtual mir::Server
271 {
272 Q_OBJECT
273
274@@ -39,18 +41,6 @@
275 MirServerConfiguration(int argc, char const* argv[], QObject* parent = 0);
276 ~MirServerConfiguration() = default;
277
278- /* mir specific */
279- std::shared_ptr<mir::compositor::Compositor> the_compositor() override;
280- std::shared_ptr<mir::scene::PlacementStrategy> the_placement_strategy() override;
281- std::shared_ptr<mir::scene::SessionListener> the_session_listener() override;
282- std::shared_ptr<mir::scene::PromptSessionListener> the_prompt_session_listener() override;
283- std::shared_ptr<mir::scene::SurfaceConfigurator> the_surface_configurator() override;
284- std::shared_ptr<mir::frontend::SessionAuthorizer> the_session_authorizer() override;
285- std::shared_ptr<mir::input::InputDispatcher> the_input_dispatcher() override;
286- std::shared_ptr<mir::graphics::GLConfig> the_gl_config() override;
287- std::shared_ptr<mir::ServerStatusListener> the_server_status_listener() override;
288- std::shared_ptr<mir::shell::FocusSetter> the_shell_focus_setter() override;
289-
290 /* qt specific */
291 // getters
292 SessionAuthorizer *sessionAuthorizer();
293
294=== modified file 'src/platforms/mirserver/mirserverintegration.cpp'
295--- src/platforms/mirserver/mirserverintegration.cpp 2014-10-01 18:42:26 +0000
296+++ src/platforms/mirserver/mirserverintegration.cpp 2014-12-02 12:30:45 +0000
297@@ -42,7 +42,6 @@
298 // Mir
299 #include <mir/graphics/display.h>
300 #include <mir/graphics/display_buffer.h>
301-#include <mir/main_loop.h>
302
303 // std
304 #include <csignal>
305@@ -179,17 +178,6 @@
306 for (QPlatformScreen *screen : m_display->screens())
307 screenAdded(screen);
308
309- // install signal handler into the Mir event loop
310- auto mainLoop = m_mirConfig->the_main_loop();
311-
312- mainLoop->register_signal_handler(
313- {SIGINT, SIGTERM},
314- [&](int)
315- {
316- qDebug() << "Signal caught by Mir, stopping Mir server..";
317- QCoreApplication::quit();
318- });
319-
320 m_clipboard->setupDBusService();
321 }
322
323
324=== modified file 'src/platforms/mirserver/qmirserver.cpp'
325--- src/platforms/mirserver/qmirserver.cpp 2014-05-16 16:45:00 +0000
326+++ src/platforms/mirserver/qmirserver.cpp 2014-12-02 12:30:45 +0000
327@@ -19,10 +19,38 @@
328 #include <QCoreApplication>
329 #include <QDebug>
330
331+#include <mir/main_loop.h>
332+
333 // local
334 #include "qmirserver.h"
335
336
337+void MirServerWorker::run()
338+{
339+ auto const main_loop = config->the_main_loop();
340+ // By enqueuing the notification code in the main loop, we are
341+ // ensuring that the server has really and fully started before
342+ // leaving wait_for_startup().
343+ main_loop->enqueue(
344+ this,
345+ [&]
346+ {
347+ std::lock_guard<std::mutex> lock(mutex);
348+ mir_running = true;
349+ started_cv.notify_one();
350+ });
351+
352+ config->run();
353+ Q_EMIT stopped();
354+}
355+
356+bool MirServerWorker::wait_for_mir_startup()
357+{
358+ std::unique_lock<decltype(mutex)> lock(mutex);
359+ started_cv.wait_for(lock, std::chrono::seconds{10}, [&]{ return mir_running; });
360+ return mir_running;
361+}
362+
363 QMirServer::QMirServer(const QSharedPointer<MirServerConfiguration> &config, QObject *parent)
364 : QObject(parent)
365 , m_mirServer(new MirServerWorker(config))
366@@ -37,6 +65,12 @@
367
368 m_mirThread.start(QThread::TimeCriticalPriority);
369 Q_EMIT run();
370+
371+ if (!m_mirServer->wait_for_mir_startup())
372+ {
373+ qCritical() << "ERROR: QMirServer - Mir failed to start";
374+ QCoreApplication::quit();
375+ }
376 }
377
378 QMirServer::~QMirServer()
379
380=== modified file 'src/platforms/mirserver/qmirserver.h'
381--- src/platforms/mirserver/qmirserver.h 2014-05-16 16:45:00 +0000
382+++ src/platforms/mirserver/qmirserver.h 2014-12-02 12:30:45 +0000
383@@ -22,28 +22,37 @@
384 #include <QThread>
385 #include <QSharedPointer>
386
387-// Mir
388-#include <mir/display_server.h>
389-
390 // local
391 #include "mirserverconfiguration.h"
392
393-// Wrap mir::DisplayServer with QObject, so it can be controlled via QThread
394-class MirServerWorker : public QObject, public mir::DisplayServer
395+#include <condition_variable>
396+#include <mutex>
397+
398+// Wrap mir::Server with QObject, so it can be controlled via QThread
399+class MirServerWorker : public QObject
400 {
401 Q_OBJECT
402
403 public:
404 MirServerWorker(const QSharedPointer<MirServerConfiguration> &config)
405- : mir::DisplayServer(*config.data())
406+ : config(config)
407 {}
408
409+ bool wait_for_mir_startup();
410+
411 Q_SIGNALS:
412 void stopped();
413
414 public Q_SLOTS:
415- void run() { mir::DisplayServer::run(); Q_EMIT stopped(); }
416- void stop() { mir::DisplayServer::stop(); }
417+ void run();
418+ void stop() { config->stop(); }
419+
420+private:
421+ std::mutex mutex;
422+ std::condition_variable started_cv;
423+ bool mir_running{false};
424+
425+ const QSharedPointer<MirServerConfiguration> config;
426 };
427
428
429
430=== modified file 'tests/modules/common/qtmir_test.h'
431--- tests/modules/common/qtmir_test.h 2014-10-06 21:23:39 +0000
432+++ tests/modules/common/qtmir_test.h 2014-12-02 12:30:45 +0000
433@@ -41,31 +41,36 @@
434
435 namespace qtmir {
436
437-class FakeMirServerConfiguration: public MirServerConfiguration
438+// Initialization of mir::Server needed for by tests
439+class TestMirServerInit : virtual mir::Server
440 {
441+public:
442+ TestMirServerInit()
443+ {
444+ override_the_prompt_session_manager(
445+ [this]{ return the_mock_prompt_session_manager(); });
446+ }
447+
448+ std::shared_ptr<mir::scene::MockPromptSessionManager> the_mock_prompt_session_manager()
449+ {
450+ return mock_prompt_session_manager;
451+ }
452+
453+private:
454 typedef testing::NiceMock<mir::scene::MockPromptSessionManager> StubPromptSessionManager;
455+ std::shared_ptr<StubPromptSessionManager> const mock_prompt_session_manager
456+ {std::make_shared<StubPromptSessionManager>()};
457+};
458+
459+class FakeMirServerConfiguration: private TestMirServerInit, public MirServerConfiguration
460+{
461 public:
462 FakeMirServerConfiguration()
463 : MirServerConfiguration(0, nullptr)
464- , mock_prompt_session_manager(std::make_shared<StubPromptSessionManager>())
465- {
466- }
467-
468- std::shared_ptr<ms::PromptSessionManager> the_prompt_session_manager() override
469- {
470- return prompt_session_manager([this]()
471- ->std::shared_ptr<ms::PromptSessionManager>
472- {
473- return the_mock_prompt_session_manager();
474- });
475- }
476-
477- std::shared_ptr<StubPromptSessionManager> the_mock_prompt_session_manager()
478- {
479- return mock_prompt_session_manager;
480- }
481-
482- std::shared_ptr<StubPromptSessionManager> mock_prompt_session_manager;
483+ {
484+ }
485+
486+ using TestMirServerInit::the_mock_prompt_session_manager;
487 };
488
489 } // namespace qtmir

Subscribers

People subscribed via source and target branches