From c1d1c0c8050d45a6316217f2e2ada632b8eddb66 Mon Sep 17 00:00:00 2001 From: David Edmundson Date: Wed, 12 Nov 2014 16:36:26 +0100 Subject: [PATCH 01/70] Replace signal handling method of detecting X startup with FD method Using SIGUSR1 to detect when X has started doesn't work with multi seat as we end up starting two X servers in such fast succession that one signal gets lost. Xorg also supports an approach where we pass a file descriptor as an argument and X will write the used dislay ID (i.e :0) into this file when it is ready. Apparently this is the preferred approach for detecting X startup. --- src/daemon/XorgDisplayServer.cpp | 55 ++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/src/daemon/XorgDisplayServer.cpp b/src/daemon/XorgDisplayServer.cpp index f10ad82..dcebb81 100644 --- a/src/daemon/XorgDisplayServer.cpp +++ b/src/daemon/XorgDisplayServer.cpp @@ -137,6 +137,17 @@ namespace SDDM { QStringList args; args << m_display << "-ac" << "-br" << "-noreset" << "-screen" << "800x600"; process->start("/usr/bin/Xephyr", args); + + + // wait for display server to start + if (!process->waitForStarted()) { + // log message + qCritical() << "Failed to start display server process."; + + // return fail + return false; + } + emit started(); } else { // set process environment QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); @@ -145,8 +156,12 @@ namespace SDDM { env.insert("XCURSOR_THEME", mainConfig.Theme.CursorTheme.get()); process->setProcessEnvironment(env); - // tell the display server to notify us when we can connect - SignalHandler::ignoreSigusr1(); + //create pipe for communicating with X server + //0 == read from X, 1== write to from X + int pipeFds[2]; + if (pipe(pipeFds) != 0) { + qCritical("Could not create pipe to start X server"); + } // start display server QStringList args; @@ -155,25 +170,39 @@ namespace SDDM { << "-nolisten" << "tcp" << "-background" << "none" << "-noreset" + << "-displayfd" << QString::number(pipeFds[1]) << QString("vt%1").arg(displayPtr()->terminalId()); qDebug() << "Running:" << qPrintable(mainConfig.XDisplay.ServerPath.get()) << qPrintable(args.join(" ")); process->start(mainConfig.XDisplay.ServerPath.get(), args); - SignalHandler::initializeSigusr1(); - connect(DaemonApp::instance()->signalHandler(), SIGNAL(sigusr1Received()), this, SIGNAL(started())); - } - // wait for display server to start - if (!process->waitForStarted()) { - // log message - qCritical() << "Failed to start display server process."; + // wait for display server to start + if (!process->waitForStarted()) { + // log message + qCritical() << "Failed to start display server process."; + + // return fail + close(pipeFds[0]); + return false; + } + + QFile readPipe; + + if (!readPipe.open(pipeFds[0], QIODevice::ReadOnly)) { + qCritical("Failed to open pipe to start X Server "); + + close(pipeFds[0]); + return false; + } + QByteArray displayNumber = readPipe.readLine(); + + + // close our pipe + close(pipeFds[0]); - // return fail - return false; - } - if (daemonApp->testing()) emit started(); + } // set flag m_started = true; -- 2.4.3