summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/perfprofiler/perfdatareader.cpp69
-rw-r--r--src/plugins/perfprofiler/perfdatareader.h10
-rw-r--r--src/plugins/perfprofiler/perfprofilerruncontrol.cpp5
3 files changed, 43 insertions, 41 deletions
diff --git a/src/plugins/perfprofiler/perfdatareader.cpp b/src/plugins/perfprofiler/perfdatareader.cpp
index ee0a1401e9..92541fd930 100644
--- a/src/plugins/perfprofiler/perfdatareader.cpp
+++ b/src/plugins/perfprofiler/perfdatareader.cpp
@@ -318,26 +318,35 @@ QStringList PerfDataReader::collectArguments(const QString &executableDirPath,
return arguments;
}
+static bool checkedWrite(QIODevice *device, const QByteArray &input)
+{
+ qint64 written = 0;
+ const qint64 size = input.size();
+ while (written < size) {
+ const qint64 bytes = device->write(input.constData() + written, size - written);
+ if (bytes < 0)
+ return false;
+
+ written += bytes;
+ }
+ return true;
+}
+
void PerfDataReader::writeChunk()
{
if (!m_buffer.isEmpty()) {
if (m_input.bytesToWrite() < s_maxBufferSize) {
- QScopedPointer<TempFile> file(m_buffer.takeFirst());
+ std::unique_ptr<Utils::TemporaryFile> file(m_buffer.takeFirst());
file->reset();
const QByteArray data(file->readAll());
- for (qint64 i = 0, end = data.length(); i < end;) {
- const qint64 written = m_input.write(data.constData() + i, end - i);
- if (written >= 0) {
- i += written;
- } else {
- m_input.disconnect();
- m_input.kill();
- emit finished();
- QMessageBox::warning(Core::ICore::mainWindow(),
- tr("Cannot send data to Perf data parser"),
- tr("The perf data parser doesn't accept further input. "
- "Your trace is incomplete."));
- }
+ if (!checkedWrite(&m_input, data)) {
+ m_input.disconnect();
+ m_input.kill();
+ emit finished();
+ QMessageBox::warning(Core::ICore::mainWindow(),
+ tr("Cannot send data to Perf data parser"),
+ tr("The perf data parser doesn't accept further input. "
+ "Your trace is incomplete."));
}
}
} else if (m_dataFinished) {
@@ -360,25 +369,23 @@ void PerfDataReader::clear()
PerfProfilerTraceFile::clear();
}
-void PerfDataReader::feedParser(const QByteArray &input)
+bool PerfDataReader::feedParser(const QByteArray &input)
{
- if (m_buffer.isEmpty()) {
- if (m_input.isOpen() && m_input.bytesToWrite() < s_maxBufferSize) {
- m_input.write(input);
- return;
- }
- TempFile *file = new TempFile;
- m_buffer.append(file);
- connect(file, &QIODevice::bytesWritten, this, &PerfDataReader::writeChunk);
- file->write(input);
- } else {
- TempFile *file = m_buffer.last();
- if (file->pos() > s_maxBufferSize) {
- file = new TempFile;
- m_buffer.append(file);
- }
- file->write(input);
+ if (!m_buffer.isEmpty()) {
+ auto *file = m_buffer.last();
+ if (file->pos() < s_maxBufferSize)
+ return checkedWrite(file, input);
+ } else if (m_input.isOpen() && m_input.bytesToWrite() < s_maxBufferSize) {
+ return checkedWrite(&m_input, input);
}
+
+ auto file = std::make_unique<Utils::TemporaryFile>("perfdatareader");
+ connect(file.get(), &QIODevice::bytesWritten, this, &PerfDataReader::writeChunk);
+ if (!file->open() || !checkedWrite(file.get(), input))
+ return false;
+
+ m_buffer.append(file.release());
+ return true;
}
QStringList PerfDataReader::findTargetArguments(const ProjectExplorer::RunConfiguration *rc) const
diff --git a/src/plugins/perfprofiler/perfdatareader.h b/src/plugins/perfprofiler/perfdatareader.h
index fffb8c7e34..8f30fa28d7 100644
--- a/src/plugins/perfprofiler/perfdatareader.h
+++ b/src/plugins/perfprofiler/perfdatareader.h
@@ -54,7 +54,7 @@ public:
QStringList findTargetArguments(const ProjectExplorer::RunConfiguration *rc) const;
void clear();
- void feedParser(const QByteArray &input);
+ bool feedParser(const QByteArray &input);
// Trigger after delay has passed
void triggerRecordingStateChange(bool recording);
@@ -81,12 +81,6 @@ protected:
private:
static const int s_maxBufferSize = 1 << 29;
- class TempFile : public Utils::TemporaryFile
- {
- public:
- TempFile() : Utils::TemporaryFile("perfdatareader") { open(); }
- };
-
QStringList collectArguments(const QString &executableDirPath,
const ProjectExplorer::Kit *kit) const;
void writeChunk();
@@ -94,7 +88,7 @@ private:
bool m_recording;
bool m_dataFinished;
QProcess m_input;
- QQueue<TempFile *> m_buffer;
+ QQueue<Utils::TemporaryFile *> m_buffer;
qint64 m_localProcessStart;
qint64 m_localRecordingEnd;
qint64 m_localRecordingStart;
diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp
index 2617285eab..d01d5c0756 100644
--- a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp
+++ b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp
@@ -225,8 +225,9 @@ void PerfProfilerRunner::start()
appendMessage(QString::fromLocal8Bit(recorder->readAllStandardError()),
Utils::StdErrFormat);
});
- connect(recorder, &DeviceProcess::readyReadStandardOutput, this, [reader, recorder] {
- reader->feedParser(recorder->readAllStandardOutput());
+ connect(recorder, &DeviceProcess::readyReadStandardOutput, this, [this, reader, recorder] {
+ if (!reader->feedParser(recorder->readAllStandardOutput()))
+ reportFailure(tr("Failed to transfer perf data to perfparser"));
});
}