Prevent main-process crash when render worker dies during IPC write

When a render-worker process crashed or exited while the worker-pool
thread was writing a control message (e.g. right after an audio-sync and
drag operation triggered a new render), the main process received SIGPIPE
and terminated at WriteControlMessage().

- Ignore SIGPIPE in main() so QProcess can report the broken pipe through
  its normal error path instead of killing the application.
- Harden WriteControlMessage() / TryWriteControlMessage() to check the
  process state and the number of bytes written before waiting.
This commit is contained in:
2026-07-13 10:19:30 +08:00
parent 01f8be7267
commit ea37dc5da6
2 changed files with 18 additions and 1 deletions
+5
View File
@@ -152,6 +152,11 @@ int main(int argc, char *argv[])
// Set up debug handler
qInstallMessageHandler(olive::DebugHandler);
// Ignore SIGPIPE so that writing to a render-worker process that has
// already crashed/closed does not terminate the main application. QProcess
// will report the failure through its normal error path instead.
signal(SIGPIPE, SIG_IGN);
// Set application metadata
QCoreApplication::setOrganizationName("oakvideoeditor.org");
QCoreApplication::setOrganizationDomain("oakvideoeditor.org");
+13 -1
View File
@@ -267,12 +267,24 @@ QString WorkerProgramPath()
bool WriteControlMessage(QProcess *process, const QJsonObject &obj)
{
if (!process || process->state() != QProcess::Running) {
return false;
}
const QByteArray line = QJsonDocument(obj).toJson(QJsonDocument::Compact) + '\n';
return process->write(line) == line.size() && process->waitForBytesWritten(5000);
const qint64 written = process->write(line);
if (written != line.size()) {
return false;
}
return process->waitForBytesWritten(5000);
}
void TryWriteControlMessage(QProcess *process, const QJsonObject &obj)
{
if (!process || process->state() != QProcess::Running) {
return;
}
const QByteArray line = QJsonDocument(obj).toJson(QJsonDocument::Compact) + '\n';
process->write(line);
}