Skip to content

Commit c1d1c0c

Browse files
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.
1 parent 0990a5e commit c1d1c0c

File tree

1 file changed

+42
-13
lines changed

1 file changed

+42
-13
lines changed

src/daemon/XorgDisplayServer.cpp

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,17 @@ namespace SDDM {
137137
QStringList args;
138138
args << m_display << "-ac" << "-br" << "-noreset" << "-screen" << "800x600";
139139
process->start("/usr/bin/Xephyr", args);
140+
141+
142+
// wait for display server to start
143+
if (!process->waitForStarted()) {
144+
// log message
145+
qCritical() << "Failed to start display server process.";
146+
147+
// return fail
148+
return false;
149+
}
150+
emit started();
140151
} else {
141152
// set process environment
142153
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
@@ -145,8 +156,12 @@ namespace SDDM {
145156
env.insert("XCURSOR_THEME", mainConfig.Theme.CursorTheme.get());
146157
process->setProcessEnvironment(env);
147158

148-
// tell the display server to notify us when we can connect
149-
SignalHandler::ignoreSigusr1();
159+
//create pipe for communicating with X server
160+
//0 == read from X, 1== write to from X
161+
int pipeFds[2];
162+
if (pipe(pipeFds) != 0) {
163+
qCritical("Could not create pipe to start X server");
164+
}
150165

151166
// start display server
152167
QStringList args;
@@ -155,25 +170,39 @@ namespace SDDM {
155170
<< "-nolisten" << "tcp"
156171
<< "-background" << "none"
157172
<< "-noreset"
173+
<< "-displayfd" << QString::number(pipeFds[1])
158174
<< QString("vt%1").arg(displayPtr()->terminalId());
159175
qDebug() << "Running:"
160176
<< qPrintable(mainConfig.XDisplay.ServerPath.get())
161177
<< qPrintable(args.join(" "));
162178
process->start(mainConfig.XDisplay.ServerPath.get(), args);
163-
SignalHandler::initializeSigusr1();
164-
connect(DaemonApp::instance()->signalHandler(), SIGNAL(sigusr1Received()), this, SIGNAL(started()));
165-
}
166179

167-
// wait for display server to start
168-
if (!process->waitForStarted()) {
169-
// log message
170-
qCritical() << "Failed to start display server process.";
180+
// wait for display server to start
181+
if (!process->waitForStarted()) {
182+
// log message
183+
qCritical() << "Failed to start display server process.";
184+
185+
// return fail
186+
close(pipeFds[0]);
187+
return false;
188+
}
189+
190+
QFile readPipe;
191+
192+
if (!readPipe.open(pipeFds[0], QIODevice::ReadOnly)) {
193+
qCritical("Failed to open pipe to start X Server ");
194+
195+
close(pipeFds[0]);
196+
return false;
197+
}
198+
QByteArray displayNumber = readPipe.readLine();
199+
200+
201+
// close our pipe
202+
close(pipeFds[0]);
171203

172-
// return fail
173-
return false;
174-
}
175-
if (daemonApp->testing())
176204
emit started();
205+
}
177206

178207
// set flag
179208
m_started = true;

0 commit comments

Comments
 (0)