Skip to content

Commit

Permalink
Enumerate drives in seperate thread
Browse files Browse the repository at this point in the history
Ref #87
  • Loading branch information
maxnet committed Jul 2, 2020
1 parent 6069e8f commit 755d7dc
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 23 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

# Adding headers explicity so they are displayed in Qt Creator
set(HEADERS config.h imagewriter.h networkaccessmanagerfactory.h nan.h drivelistitem.h drivelistmodel.h driveformatthread.h powersaveblocker.h
set(HEADERS config.h imagewriter.h networkaccessmanagerfactory.h nan.h drivelistitem.h drivelistmodel.h drivelistmodelpollthread.h driveformatthread.h powersaveblocker.h
downloadthread.h downloadextractthread.h localfileextractthread.h dependencies/mountutils/src/mountutils.hpp)

# Add dependencies
Expand Down Expand Up @@ -67,7 +67,7 @@ if (NOT atomicbuiltin)
endif()

set(SOURCES "main.cpp" "imagewriter.cpp" "networkaccessmanagerfactory.cpp"
"drivelistitem.cpp" "drivelistmodel.cpp" "downloadthread.cpp" "downloadextractthread.cpp"
"drivelistitem.cpp" "drivelistmodel.cpp" "drivelistmodelpollthread.cpp" "downloadthread.cpp" "downloadextractthread.cpp"
"driveformatthread.cpp" "localfileextractthread.cpp" "powersaveblocker.cpp" "qml.qrc")

find_package(Qt5 COMPONENTS Core Quick LinguistTools Svg OPTIONAL_COMPONENTS Widgets)
Expand Down
16 changes: 14 additions & 2 deletions drivelistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ DriveListModel::DriveListModel(QObject *parent)
{isScsiRole, "isScsi"},
{mountpointsRole, "mountpoints"}
};

// Enumerate drives in seperate thread, but process results in UI thread
connect(&_thread, SIGNAL(newDriveList(std::vector<Drivelist::DeviceDescriptor>)), SLOT(processDriveList(std::vector<Drivelist::DeviceDescriptor>)));
}

int DriveListModel::rowCount(const QModelIndex &) const
Expand All @@ -45,11 +48,10 @@ QVariant DriveListModel::data(const QModelIndex &index, int role) const
return _drivelist.values().at(row)->property(propertyName);
}

void DriveListModel::refreshDriveList()
void DriveListModel::processDriveList(std::vector<Drivelist::DeviceDescriptor> l)
{
bool changes = false;
bool filterSystemDrives = DRIVELIST_FILTER_SYSTEM_DRIVES;
auto l = Drivelist::ListStorageDevices();
QSet<QString> drivesInNewList;

for (auto &i: l)
Expand Down Expand Up @@ -117,3 +119,13 @@ void DriveListModel::refreshDriveList()
if (changes)
endResetModel();
}

void DriveListModel::startPolling()
{
_thread.start();
}

void DriveListModel::stopPolling()
{
_thread.stop();
}
7 changes: 6 additions & 1 deletion drivelistmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,30 @@
#include <QMap>
#include <QHash>
#include "drivelistitem.h"
#include "drivelistmodelpollthread.h"

class DriveListModel : public QAbstractListModel
{
Q_OBJECT
public:
DriveListModel(QObject *parent = nullptr);
virtual int rowCount(const QModelIndex &) const;
virtual QHash<int, QByteArray> roleNames() const;
virtual QVariant data(const QModelIndex &index, int role) const;
void startPolling();
void stopPolling();

enum driveListRoles {
deviceRole = Qt::UserRole + 1, descriptionRole, sizeRole, isUsbRole, isScsiRole, mountpointsRole
};

public slots:
void refreshDriveList();
void processDriveList(std::vector<Drivelist::DeviceDescriptor> l);

protected:
QMap<QString,DriveListItem *> _drivelist;
QHash<int, QByteArray> _rolenames;
DriveListModelPollThread _thread;
};

#endif // DRIVELISTMODEL_H
47 changes: 47 additions & 0 deletions drivelistmodelpollthread.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "drivelistmodelpollthread.h"
#include <QElapsedTimer>
#include <QDebug>

/*
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2020 Raspberry Pi (Trading) Limited
*/

DriveListModelPollThread::DriveListModelPollThread(QObject *parent)
: QThread(parent), _terminate(false)
{
qRegisterMetaType< std::vector<Drivelist::DeviceDescriptor> >( "std::vector<Drivelist::DeviceDescriptor>" );
}

DriveListModelPollThread::~DriveListModelPollThread()
{
_terminate = true;
if (!wait(2000)) {
terminate();
}
}

void DriveListModelPollThread::stop()
{
_terminate = true;
}

void DriveListModelPollThread::start()
{
_terminate = false;
QThread::start();
}

void DriveListModelPollThread::run()
{
QElapsedTimer t1;

while (!_terminate)
{
t1.start();
emit newDriveList( Drivelist::ListStorageDevices() );
if (t1.elapsed() > 1000)
qDebug() << "Enumerating drives took a long time:" << t1.elapsed()/1000.0 << "seconds";
QThread::sleep(1);
}
}
29 changes: 29 additions & 0 deletions drivelistmodelpollthread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef DRIVELISTMODELPOLLTHREAD_H
#define DRIVELISTMODELPOLLTHREAD_H

/*
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2020 Raspberry Pi (Trading) Limited
*/

#include <QThread>
#include "dependencies/drivelist/src/drivelist.hpp"

class DriveListModelPollThread : public QThread
{
Q_OBJECT
public:
DriveListModelPollThread(QObject *parent = nullptr);
~DriveListModelPollThread();
void start();
void stop();

protected:
bool _terminate;
virtual void run() override;

signals:
void newDriveList(std::vector<Drivelist::DeviceDescriptor> list);
};

#endif // DRIVELISTMODELPOLLTHREAD_H
12 changes: 9 additions & 3 deletions imagewriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,16 @@ void ImageWriter::setCustomOsListUrl(const QUrl &url)
_repo = url;
}

/* Refresh the list of available drives */
void ImageWriter::refreshDriveList()
/* Start polling the list of available drives */
void ImageWriter::startDriveListPolling()
{
_drivelist.refreshDriveList();
_drivelist.startPolling();
}

/* Stop polling the list of available drives */
void ImageWriter::stopDriveListPolling()
{
_drivelist.stopPolling();
}

DriveListModel *ImageWriter::getDriveList()
Expand Down
9 changes: 6 additions & 3 deletions imagewriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,13 @@ class ImageWriter : public QObject
/* Return true if url is in our local disk cache */
Q_INVOKABLE bool isCached(const QUrl &url, const QByteArray &sha256);

/* Refresh the list of available drives */
Q_INVOKABLE void refreshDriveList();
/* Start polling the list of available drives */
Q_INVOKABLE void startDriveListPolling();

/* Return list of available drives. Call refreshDriveList() first */
/* Stop polling the list of available drives */
Q_INVOKABLE void stopDriveListPolling();

/* Return list of available drives. Call startDriveListPolling() first */
DriveListModel *getDriveList();

/* Utility function to return filename part from URL */
Expand Down
14 changes: 2 additions & 12 deletions main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ ApplicationWindow {
Layout.preferredWidth: 100
Layout.fillWidth: true
onClicked: {
imageWriter.refreshDriveList()
drivePollTimer.start()
imageWriter.startDriveListPolling()
dstpopup.open()
dstlist.forceActiveFocus()
}
Expand Down Expand Up @@ -546,6 +545,7 @@ ApplicationWindow {
height: parent.height-50
padding: 0
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
onClosed: imageWriter.stopDriveListPolling()

// background of title
Rectangle {
Expand Down Expand Up @@ -616,7 +616,6 @@ ApplicationWindow {
if (currentIndex == -1)
return

drivePollTimer.stop()
dstpopup.close()
imageWriter.setDst(currentItem.device, currentItem.size)
dstbutton.text = currentItem.description
Expand All @@ -628,7 +627,6 @@ ApplicationWindow {
if (currentIndex == -1)
return

drivePollTimer.stop()
dstpopup.close()
imageWriter.setDst(currentItem.device, currentItem.size)
dstbutton.text = currentItem.description
Expand Down Expand Up @@ -720,7 +718,6 @@ ApplicationWindow {
}

onClicked: {
drivePollTimer.stop()
dstpopup.close()
imageWriter.setDst(device, size)
dstbutton.text = description
Expand Down Expand Up @@ -784,13 +781,6 @@ ApplicationWindow {
property alias y: window.y
}

/* Timer for polling drivelist changes */
Timer {
id: drivePollTimer
repeat: true
onTriggered: imageWriter.refreshDriveList()
}

/* Utility functions */
function httpRequest(url, callback) {
var xhr = new XMLHttpRequest();
Expand Down

0 comments on commit 755d7dc

Please sign in to comment.