QtcProcess: Get rid of NoSignal synthetic value

Refactor flushing methods.

Change-Id: I1b98de58e8ddacfa5ff7e1627c5011c0bd207a8b
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2022-06-08 08:27:26 +02:00
parent 674f62d481
commit cf47ad361d

View File

@@ -486,7 +486,6 @@ static ProcessImpl defaultProcessImpl()
} }
enum class SignalType { enum class SignalType {
NoSignal,
Started, Started,
ReadyRead, ReadyRead,
Done Done
@@ -653,8 +652,16 @@ public:
// === ProcessInterfaceHandler related === // === ProcessInterfaceHandler related ===
// Called from caller's thread exclusively // Called from caller's thread exclusively
bool waitForSignal(int msecs, SignalType newSignal); bool waitForSignal(int msecs, SignalType newSignal);
void flush() { flushFor(SignalType::NoSignal); } void flush() { flushSignals(takeAllSignals()); }
bool flushFor(SignalType signalType); bool flushFor(SignalType signalType) {
return flushSignals(takeSignalsFor(signalType), &signalType);
}
QList<ProcessInterfaceSignal *> takeAllSignals();
QList<ProcessInterfaceSignal *> takeSignalsFor(SignalType signalType);
bool flushSignals(const QList<ProcessInterfaceSignal *> &signalList,
SignalType *signalType = nullptr);
bool shouldFlush() const { QMutexLocker locker(&m_mutex); return !m_signals.isEmpty(); } bool shouldFlush() const { QMutexLocker locker(&m_mutex); return !m_signals.isEmpty(); }
Qt::ConnectionType connectionType() const; Qt::ConnectionType connectionType() const;
void sendControlSignal(ControlSignal controlSignal, int killTimeout = -1); void sendControlSignal(ControlSignal controlSignal, int killTimeout = -1);
@@ -797,42 +804,50 @@ bool QtcProcessPrivate::waitForSignal(int msecs, SignalType newSignal)
} }
// Called from caller's thread exclusively // Called from caller's thread exclusively
bool QtcProcessPrivate::flushFor(SignalType signalType) QList<ProcessInterfaceSignal *> QtcProcessPrivate::takeAllSignals()
{ {
QList<ProcessInterfaceSignal *> oldSignals; QMutexLocker locker(&m_mutex);
{ return std::exchange(m_signals, {});
QMutexLocker locker(&m_mutex); }
const QList<SignalType> storedSignals = transform(qAsConst(m_signals),
[](const ProcessInterfaceSignal *aSignal) {
return aSignal->signalType();
});
// If we are flushing for ReadyRead or Done - flush all. // Called from caller's thread exclusively
// If we are flushing for Started: QList<ProcessInterfaceSignal *> QtcProcessPrivate::takeSignalsFor(SignalType signalType)
// - if Started was buffered - flush Started only. {
// - otherwise if Done signal was buffered - flush all. // If we are flushing for ReadyRead or Done - flush all.
const bool flushAll = (signalType != SignalType::Started) if (signalType != SignalType::Started)
|| (!storedSignals.contains(SignalType::Started) return takeAllSignals();
&& storedSignals.contains(SignalType::Done));
if (flushAll) { QMutexLocker locker(&m_mutex);
oldSignals = m_signals; const QList<SignalType> storedSignals = transform(qAsConst(m_signals),
m_signals = {}; [](const ProcessInterfaceSignal *aSignal) {
} else { return aSignal->signalType();
auto matchingIndex = storedSignals.lastIndexOf(signalType); });
if (matchingIndex >= 0) {
oldSignals = m_signals.mid(0, matchingIndex + 1); // If we are flushing for Started:
m_signals = m_signals.mid(matchingIndex + 1); // - if Started was buffered - flush Started only (even when Done was buffered)
} // - otherwise if Done signal was buffered - flush all.
} if (!storedSignals.contains(SignalType::Started) && storedSignals.contains(SignalType::Done))
return std::exchange(m_signals, {}); // avoid takeAllSignals() because of mutex locked
QList<ProcessInterfaceSignal *> oldSignals;
const auto matchingIndex = storedSignals.lastIndexOf(signalType);
if (matchingIndex >= 0) {
oldSignals = m_signals.mid(0, matchingIndex + 1);
m_signals = m_signals.mid(matchingIndex + 1);
} }
return oldSignals;
}
// Called from caller's thread exclusively
bool QtcProcessPrivate::flushSignals(const QList<ProcessInterfaceSignal *> &signalList,
SignalType *signalType)
{
bool signalMatched = false; bool signalMatched = false;
for (const ProcessInterfaceSignal *storedSignal : qAsConst(oldSignals)) { for (const ProcessInterfaceSignal *storedSignal : qAsConst(signalList)) {
const SignalType storedSignalType = storedSignal->signalType(); const SignalType storedSignalType = storedSignal->signalType();
if (storedSignalType == signalType) if (signalType && storedSignalType == *signalType)
signalMatched = true; signalMatched = true;
switch (storedSignalType) { switch (storedSignalType) {
case SignalType::NoSignal:
break;
case SignalType::Started: case SignalType::Started:
handleStartedSignal(static_cast<const StartedSignal *>(storedSignal)); handleStartedSignal(static_cast<const StartedSignal *>(storedSignal));
break; break;
@@ -840,7 +855,8 @@ bool QtcProcessPrivate::flushFor(SignalType signalType)
handleReadyReadSignal(static_cast<const ReadyReadSignal *>(storedSignal)); handleReadyReadSignal(static_cast<const ReadyReadSignal *>(storedSignal));
break; break;
case SignalType::Done: case SignalType::Done:
signalMatched = true; if (signalType)
signalMatched = true;
handleDoneSignal(static_cast<const DoneSignal *>(storedSignal)); handleDoneSignal(static_cast<const DoneSignal *>(storedSignal));
break; break;
} }
@@ -880,8 +896,6 @@ void QtcProcessPrivate::kill()
// Called from ProcessInterfaceHandler thread exclusively. // Called from ProcessInterfaceHandler thread exclusively.
void QtcProcessPrivate::appendSignal(ProcessInterfaceSignal *newSignal) void QtcProcessPrivate::appendSignal(ProcessInterfaceSignal *newSignal)
{ {
QTC_ASSERT(newSignal->signalType() != SignalType::NoSignal, delete newSignal; return);
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
m_signals.append(newSignal); m_signals.append(newSignal);
} }