kio/0001-Dont-stat-etc-localtime-between-read-and-write.patch

126 lines
4.2 KiB
Diff

From 8d73867b3d4339ec026f92c4c2e89c265249aeb2 Mon Sep 17 00:00:00 2001
From: Jaime Torres <jtamate@gmail.com>
Date: Wed, 7 Feb 2018 19:02:16 +0100
Subject: Don't stat(/etc/localtime) between read() and write() copying files
Summary:
CCBUG: 384561
Unfortunately, QDateTime::currentDateTime() checks /etc/localtime
each time it is called.
Chaning to QElapsedTime, no check of /etc/localtime.
Reproducing bug 384561, the strace of file.so was something like:
read(), stat(/etc/localtime), stat(/etc/localtime),
stat(/etc/localtime), stat(/etc/localtime), stat(/etc/localtime),
write(), read() ......
Now it is: read(), write()
It also reduces the cpu in io/wait around 10% in a debug build.
Test Plan:
kio tests work as before
desktop: works in dolphin
Reviewers: #frameworks, fvogt, dfaure
Reviewed By: dfaure
Subscribers: fvogt, ngraham
Tags: #frameworks
Differential Revision: https://phabricator.kde.org/D9983
---
src/core/slavebase.cpp | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/src/core/slavebase.cpp b/src/core/slavebase.cpp
index 4f8a5da..5e8effb 100644
--- a/src/core/slavebase.cpp
+++ b/src/core/slavebase.cpp
@@ -80,7 +80,7 @@ class SlaveBasePrivate
{
public:
SlaveBase *q;
- SlaveBasePrivate(SlaveBase *owner): q(owner), m_passwdServerClient(nullptr)
+ SlaveBasePrivate(SlaveBase *owner): q(owner), nextTimeoutMsecs(0), m_passwdServerClient(nullptr)
{
if (!qEnvironmentVariableIsEmpty("KIOSLAVE_ENABLE_TESTMODE")) {
QStandardPaths::enableTestMode(true);
@@ -110,8 +110,9 @@ public:
KConfigGroup *configGroup;
QUrl onHoldUrl;
- QDateTime lastTimeout;
- QDateTime nextTimeout;
+ QElapsedTimer lastTimeout;
+ QElapsedTimer nextTimeout;
+ qint64 nextTimeoutMsecs;
KIO::filesize_t totalSize;
KRemoteEncoding *remotefile;
enum { Idle, InsideMethod, FinishedCalled, ErrorCalled } m_state;
@@ -273,9 +274,9 @@ SlaveBase::~SlaveBase()
void SlaveBase::dispatchLoop()
{
while (!d->exit_loop) {
- if (d->nextTimeout.isValid() && (d->nextTimeout < QDateTime::currentDateTime())) {
+ if (d->nextTimeout.isValid() && (d->nextTimeout.hasExpired(d->nextTimeoutMsecs))) {
QByteArray data = d->timeoutData;
- d->nextTimeout = QDateTime();
+ d->nextTimeout.invalidate();
d->timeoutData = QByteArray();
special(data);
}
@@ -284,7 +285,7 @@ void SlaveBase::dispatchLoop()
int ms = -1;
if (d->nextTimeout.isValid()) {
- ms = qMax<int>(QDateTime::currentDateTime().msecsTo(d->nextTimeout), 1);
+ ms = qMax<int>(d->nextTimeout.elapsed() - d->nextTimeoutMsecs, 1);
}
int ret = -1;
@@ -529,13 +530,11 @@ void SlaveBase::processedSize(KIO::filesize_t _bytes)
{
bool emitSignal = false;
- QDateTime now = QDateTime::currentDateTime();
-
if (_bytes == d->totalSize) {
emitSignal = true;
} else {
if (d->lastTimeout.isValid()) {
- emitSignal = d->lastTimeout.msecsTo(now) >= 100; // emit size 10 times a second
+ emitSignal = d->lastTimeout.hasExpired(100); // emit size 10 times a second
} else {
emitSignal = true;
}
@@ -544,7 +543,7 @@ void SlaveBase::processedSize(KIO::filesize_t _bytes)
if (emitSignal) {
KIO_DATA << KIO_FILESIZE_T(_bytes);
send(INF_PROCESSED_SIZE, data);
- d->lastTimeout = now;
+ d->lastTimeout.start();
}
// d->processed_size = _bytes;
@@ -1046,11 +1045,13 @@ int SlaveBase::readData(QByteArray &buffer)
void SlaveBase::setTimeoutSpecialCommand(int timeout, const QByteArray &data)
{
if (timeout > 0) {
- d->nextTimeout = QDateTime::currentDateTime().addSecs(timeout);
+ d->nextTimeoutMsecs = timeout*1000; // from seconds to miliseconds
+ d->nextTimeout.start();
} else if (timeout == 0) {
- d->nextTimeout = QDateTime::currentDateTime().addSecs(1); // Immediate timeout
+ d->nextTimeoutMsecs = 1000; // Immediate timeout
+ d->nextTimeout.start();
} else {
- d->nextTimeout = QDateTime(); // Canceled
+ d->nextTimeout.invalidate(); // Canceled
}
d->timeoutData = data;
--
cgit v0.11.2