Prefer QThreadPool over QtConcurrent where we don't care about result
QtConcurrent::run()'s return type is marked with [[nodiscard]], which is not nice to code that just needs to move some tasks to a worker thread. On the other hand, QThreadPool satisfies our needs too and Qt doesn't need to construct futures that we won't use. One remark about the screenshot plugin: the task lambda is mutable so it cannot be represented using a std::function.
This commit is contained in:
parent
a2ef5cb1a7
commit
983a0bc599
7 changed files with 91 additions and 84 deletions
|
@ -18,7 +18,6 @@ target_link_libraries(screenshot PRIVATE
|
|||
KF6::Service
|
||||
KF6::I18n
|
||||
|
||||
Qt::Concurrent
|
||||
Qt::DBus
|
||||
)
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QtConcurrent>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -27,6 +27,77 @@
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class ScreenShotWriter2 : public QRunnable
|
||||
{
|
||||
public:
|
||||
ScreenShotWriter2(FileDescriptor &&fileDescriptor, const QImage &image)
|
||||
: m_fileDescriptor(std::move(fileDescriptor))
|
||||
, m_image(image)
|
||||
{
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
const int flags = fcntl(m_fileDescriptor.get(), F_GETFL, 0);
|
||||
if (flags == -1) {
|
||||
qCWarning(KWIN_SCREENSHOT) << "failed to get screenshot fd flags:" << strerror(errno);
|
||||
return;
|
||||
}
|
||||
if (!(flags & O_NONBLOCK)) {
|
||||
if (fcntl(m_fileDescriptor.get(), F_SETFL, flags | O_NONBLOCK) == -1) {
|
||||
qCWarning(KWIN_SCREENSHOT) << "failed to make screenshot fd non blocking:" << strerror(errno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QFile file;
|
||||
if (!file.open(m_fileDescriptor.get(), QIODevice::WriteOnly)) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "failed to open pipe:" << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
const QByteArrayView buffer(m_image.constBits(), m_image.sizeInBytes());
|
||||
qint64 remainingSize = buffer.size();
|
||||
|
||||
pollfd pfds[1];
|
||||
pfds[0].fd = m_fileDescriptor.get();
|
||||
pfds[0].events = POLLOUT;
|
||||
|
||||
while (true) {
|
||||
const int ready = poll(pfds, 1, 60000);
|
||||
if (ready < 0) {
|
||||
if (errno != EINTR) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "poll() failed:" << strerror(errno);
|
||||
return;
|
||||
}
|
||||
} else if (ready == 0) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "timed out writing to pipe";
|
||||
return;
|
||||
} else if (!(pfds[0].revents & POLLOUT)) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "pipe is broken";
|
||||
return;
|
||||
} else {
|
||||
const char *chunk = buffer.constData() + (buffer.size() - remainingSize);
|
||||
const qint64 writtenCount = file.write(chunk, remainingSize);
|
||||
|
||||
if (writtenCount < 0) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "write() failed:" << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
remainingSize -= writtenCount;
|
||||
if (writtenCount == 0 || remainingSize == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
FileDescriptor m_fileDescriptor;
|
||||
QImage m_image;
|
||||
};
|
||||
|
||||
static ScreenShotFlags screenShotFlagsFromOptions(const QVariantMap &options)
|
||||
{
|
||||
ScreenShotFlags flags = ScreenShotFlags();
|
||||
|
@ -49,62 +120,6 @@ static ScreenShotFlags screenShotFlagsFromOptions(const QVariantMap &options)
|
|||
return flags;
|
||||
}
|
||||
|
||||
static void writeBufferToPipe(FileDescriptor fileDescriptor, const QByteArray &buffer)
|
||||
{
|
||||
const int flags = fcntl(fileDescriptor.get(), F_GETFL, 0);
|
||||
if (flags == -1) {
|
||||
qCWarning(KWIN_SCREENSHOT) << "failed to get screenshot fd flags:" << strerror(errno);
|
||||
return;
|
||||
}
|
||||
if (!(flags & O_NONBLOCK)) {
|
||||
if (fcntl(fileDescriptor.get(), F_SETFL, flags | O_NONBLOCK) == -1) {
|
||||
qCWarning(KWIN_SCREENSHOT) << "failed to make screenshot fd non blocking:" << strerror(errno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QFile file;
|
||||
if (!file.open(fileDescriptor.get(), QIODevice::WriteOnly)) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "failed to open pipe:" << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
qint64 remainingSize = buffer.size();
|
||||
|
||||
pollfd pfds[1];
|
||||
pfds[0].fd = fileDescriptor.get();
|
||||
pfds[0].events = POLLOUT;
|
||||
|
||||
while (true) {
|
||||
const int ready = poll(pfds, 1, 60000);
|
||||
if (ready < 0) {
|
||||
if (errno != EINTR) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "poll() failed:" << strerror(errno);
|
||||
return;
|
||||
}
|
||||
} else if (ready == 0) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "timed out writing to pipe";
|
||||
return;
|
||||
} else if (!(pfds[0].revents & POLLOUT)) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "pipe is broken";
|
||||
return;
|
||||
} else {
|
||||
const char *chunk = buffer.constData() + (buffer.size() - remainingSize);
|
||||
const qint64 writtenCount = file.write(chunk, remainingSize);
|
||||
|
||||
if (writtenCount < 0) {
|
||||
qCWarning(KWIN_SCREENSHOT) << Q_FUNC_INFO << "write() failed:" << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
remainingSize -= writtenCount;
|
||||
if (writtenCount == 0 || remainingSize == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const QString s_dbusServiceName = QStringLiteral("org.kde.KWin.ScreenShot2");
|
||||
static const QString s_dbusInterface = QStringLiteral("org.kde.KWin.ScreenShot2");
|
||||
static const QString s_dbusObjectPath = QStringLiteral("/org/kde/KWin/ScreenShot2");
|
||||
|
@ -287,11 +302,9 @@ void ScreenShotSinkPipe2::flush(const QImage &image, const QVariantMap &attribut
|
|||
results.insert(QStringLiteral("scale"), double(image.devicePixelRatio()));
|
||||
QDBusConnection::sessionBus().send(m_replyMessage.createReply(results));
|
||||
|
||||
QtConcurrent::run([fileDescriptor = std::move(m_fileDescriptor), image]() mutable {
|
||||
const QByteArray buffer(reinterpret_cast<const char *>(image.constBits()),
|
||||
image.sizeInBytes());
|
||||
writeBufferToPipe(std::move(fileDescriptor), buffer);
|
||||
});
|
||||
auto writer = new ScreenShotWriter2(std::move(m_fileDescriptor), image);
|
||||
writer->setAutoDelete(true);
|
||||
QThreadPool::globalInstance()->start(writer);
|
||||
}
|
||||
|
||||
ScreenShotDBusInterface2::ScreenShotDBusInterface2(ScreenShotEffect *effect)
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include <QAction>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include <KGlobalAccel>
|
||||
#include <KLazyLocalizedString>
|
||||
|
@ -186,9 +185,7 @@ void UserActionsMenu::helperDialog(const QString &message, Window *window)
|
|||
if (window) {
|
||||
args << QStringLiteral("--embed") << QString::number(window->window());
|
||||
}
|
||||
QtConcurrent::run([args]() {
|
||||
KProcess::startDetached(QStringLiteral("kdialog"), args);
|
||||
});
|
||||
KProcess::startDetached(QStringLiteral("kdialog"), args);
|
||||
}
|
||||
|
||||
QStringList configModules(bool controlCenter)
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
#include <QIcon>
|
||||
#include <QList>
|
||||
#include <QRect>
|
||||
#include <QThreadPool>
|
||||
#include <QUuid>
|
||||
#include <QVector>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
#include <qwayland-server-plasma-window-management.h>
|
||||
|
||||
|
@ -466,15 +466,13 @@ void PlasmaWindowInterfacePrivate::setResourceName(const QString &resourceName)
|
|||
|
||||
void PlasmaWindowInterfacePrivate::org_kde_plasma_window_get_icon(Resource *resource, int32_t fd)
|
||||
{
|
||||
QtConcurrent::run(
|
||||
[fd](const QIcon &icon) {
|
||||
QFile file;
|
||||
file.open(fd, QIODevice::WriteOnly, QFileDevice::AutoCloseHandle);
|
||||
QDataStream ds(&file);
|
||||
ds << icon;
|
||||
file.close();
|
||||
},
|
||||
m_icon);
|
||||
QThreadPool::globalInstance()->start([fd, icon = m_icon]() {
|
||||
QFile file;
|
||||
file.open(fd, QIODevice::WriteOnly, QFileDevice::AutoCloseHandle);
|
||||
QDataStream ds(&file);
|
||||
ds << icon;
|
||||
file.close();
|
||||
});
|
||||
}
|
||||
|
||||
void PlasmaWindowInterfacePrivate::org_kde_plasma_window_request_enter_virtual_desktop(Resource *resource, const QString &id)
|
||||
|
|
|
@ -17,7 +17,7 @@ if (TARGET Qt::Widgets)
|
|||
fakeoutput.cpp
|
||||
)
|
||||
add_executable(testRenderingServer ${testRenderingServer_SRCS})
|
||||
target_link_libraries(testRenderingServer kwin Qt::Concurrent Qt::Widgets)
|
||||
target_link_libraries(testRenderingServer kwin Qt::Core Qt::Widgets)
|
||||
ecm_mark_as_test(testRenderingServer)
|
||||
endif()
|
||||
|
||||
|
@ -26,7 +26,7 @@ target_link_libraries(copyClient KF6::WaylandClient)
|
|||
ecm_mark_as_test(copyClient)
|
||||
|
||||
add_executable(pasteClient pasteclient.cpp)
|
||||
target_link_libraries(pasteClient Qt::Concurrent KF6::WaylandClient)
|
||||
target_link_libraries(pasteClient Qt::Core KF6::WaylandClient)
|
||||
ecm_mark_as_test(pasteClient)
|
||||
|
||||
add_executable(touchClientTest touchclienttest.cpp)
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
#include <QFile>
|
||||
#include <QImage>
|
||||
#include <QMimeType>
|
||||
#include <QThread>
|
||||
#include <QtConcurrentRun>
|
||||
#include <QThreadPool>
|
||||
// system
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -137,7 +136,7 @@ void PasteClient::setupRegistry(Registry *registry)
|
|||
}
|
||||
dataOffer->receive((*it).name(), pipeFds[1]);
|
||||
close(pipeFds[1]);
|
||||
QtConcurrent::run([pipeFds] {
|
||||
QThreadPool::globalInstance()->start([pipeFds] {
|
||||
QFile readPipe;
|
||||
if (readPipe.open(pipeFds[0], QIODevice::ReadOnly)) {
|
||||
qDebug() << "Pasted: " << readPipe.readLine();
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QKeyEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QThreadPool>
|
||||
#include <QWidget>
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
@ -274,7 +275,7 @@ int main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
QtConcurrent::run([pipe] {
|
||||
QThreadPool::globalInstance()->start([pipe] {
|
||||
readDisplayFromPipe(pipe);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue