Commit e1c19ce4 authored by Oleg Solovyov's avatar Oleg Solovyov 🐴 Committed by Nate Graham
Browse files

Plasmashell freezes when trying to get free space info from mounted remote...

Plasmashell freezes when trying to get free space info from mounted remote filesystem after losing connection to it

BUG: 397537

Earlier plasmashell assumed that you'll get free space info immediately (which is not true in case of losing connection to server containing a mounted filesystem - statfs will wait for response forever and freeze everything since it's happening in main thread)

I moved obtaining that info into different thread so that case won't freeze anything anymore.
It creates exactly one thread per one path. If a path is already being processed, new thread won't be created.
Also I implemented a timer used to notify about broken connection after 15 seconds.

Reviewers: broulik, ngraham, davidedmundson

Reviewed By: broulik

Subscribers: ngraham, anthonyfieroni, davidedmundson, plasma-devel

Tags: #plasma

Differential Revision:
parent 2949e7c4
......@@ -18,6 +18,7 @@ target_link_libraries(plasma_engine_soliddevice
kcoreaddons_desktop_to_json(plasma_engine_soliddevice plasma-dataengine-soliddevice.desktop)
......@@ -24,9 +24,11 @@
#include <Solid/GenericInterface>
#include <klocalizedstring.h>
#include <QApplication>
#include <QDebug>
#include <KDiskFreeSpaceInfo>
#include <KFormat>
#include <KIO/FileSystemFreeSpaceJob>
#include <KNotification>
#include <Plasma/DataContainer>
......@@ -547,12 +549,39 @@ bool SolidDeviceEngine::updateStorageSpace(const QString &udi)
return false;
KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(storageaccess->filePath());
if (info.isValid()) {
setData(udi, I18N_NOOP("Free Space"), QVariant(info.available()));
setData(udi, I18N_NOOP("Free Space Text"), KFormat().formatByteSize(info.available()));
setData(udi, I18N_NOOP("Size"), QVariant(info.size()));
return true;
QString path = storageaccess->filePath();
if (!m_paths.contains(path)) {
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, [path]() {
KNotification::event(KNotification::Error, i18n("Filesystem is not responding", path),
i18n("Filesystem mounted at '%1' is not responding", path));
// create job
KIO::FileSystemFreeSpaceJob *job = KIO::fileSystemFreeSpace(QUrl::fromLocalFile(path));
// delete later timer
connect(job, &KIO::FileSystemFreeSpaceJob::result, timer, &QTimer::deleteLater);
// collect and process info
connect(job, &KIO::FileSystemFreeSpaceJob::result, this,
[this, timer, path, udi](KIO::Job *job, KIO::filesize_t size, KIO::filesize_t available) {
if (!job->error()) {
setData(udi, I18N_NOOP("Free Space"), QVariant(available));
setData(udi, I18N_NOOP("Free Space Text"), KFormat().formatByteSize(available));
setData(udi, I18N_NOOP("Size"), QVariant(size));
// start timer: after 15 seconds we will get an error
return false;
......@@ -35,6 +35,7 @@
#include "devicesignalmapmanager.h"
#include "devicesignalmapper.h"
#include "hddtemp.h"
#include <KIO/FileSystemFreeSpaceJob>
enum State {
Idle = 0,
......@@ -80,6 +81,8 @@ private:
QMap<QString, Solid::Device> m_devicemap;
//udi, corresponding encrypted container udi;
QMap<QString, QString> m_encryptedContainerMap;
//path, corresponding timer
QSet<QString> m_paths;
DeviceSignalMapManager *m_signalmanager;
HddTemp *m_temperature;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment