Skip to content

Commit 7a5ce88

Browse files
committed
chore: move readpipedatatask logic to waylandcopyclient
move the logic to waylandcopyclient, seems it will reduced when the signal cannot received by task Log:
1 parent f877f4c commit 7a5ce88

File tree

2 files changed

+91
-5
lines changed

2 files changed

+91
-5
lines changed

dde-clipboard-daemon/waylandcopyclient.cpp

+86-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

55
#include "waylandcopyclient.h"
6-
#include "readpipedatatask.h"
76

87
#include <QEventLoop>
98
#include <QMimeData>
@@ -22,6 +21,11 @@
2221
#include <DWayland/Client/datacontroloffer.h>
2322

2423
#include <unistd.h>
24+
#include <mutex>
25+
26+
static std::mutex PIPELINE_GUARD;
27+
28+
constexpr int BYTE_MAX = 1024 * 4;
2529

2630
static const QString ApplicationXQtImageLiteral QStringLiteral("application/x-qt-image");
2731

@@ -167,6 +171,7 @@ void WaylandCopyClient::init()
167171
m_connectionThread->start();
168172
m_connectionThreadObject->initConnection();
169173
connect(this, &WaylandCopyClient::dataCopied, this, &WaylandCopyClient::onDataCopied);
174+
connect(this, &WaylandCopyClient::dataReady, this, &WaylandCopyClient::taskDataReady);
170175
}
171176

172177
void WaylandCopyClient::setupRegistry(Registry *registry)
@@ -217,13 +222,89 @@ void WaylandCopyClient::onDataOffered(KWayland::Client::DataControlOfferV1* offe
217222
// NOTE: no thread, this should be block
218223
void WaylandCopyClient::execTask(const QStringList &mimeTypes, DataControlOfferV1 *offer)
219224
{
225+
m_pipeIsForcedClosed = false;
220226
for (const QString &mimeType : mimeTypes) {
221-
ReadPipeDataTask *task = new ReadPipeDataTask(m_connectionThreadObject, offer, mimeType, this);
222-
connect(this, &WaylandCopyClient::dataOfferedNew, task, &ReadPipeDataTask::forceClosePipeLine);
223-
connect(task, &ReadPipeDataTask::dataReady, this, &WaylandCopyClient::taskDataReady);
227+
onDataOfferedTask(offer, mimeType);
228+
}
229+
}
224230

225-
task->run();
231+
void WaylandCopyClient::onDataOfferedTask(DataControlOfferV1 *offer, const QString &mimeType)
232+
{
233+
if (!m_connectionThreadObject || !offer || mimeType.isEmpty()) {
234+
return;
226235
}
236+
int pipeFds[2];
237+
238+
if (pipe(pipeFds) != 0) {
239+
qWarning() << "Create pipe failed.";
240+
241+
// 避免返回数据量少
242+
Q_EMIT dataReady((qint64)offer, mimeType, QByteArray());
243+
return;
244+
}
245+
246+
// 根据mime类取数据,写入pipe中
247+
offer->receive(mimeType, pipeFds[1]);
248+
m_connectionThreadObject->roundtrip();
249+
close(pipeFds[1]);
250+
251+
// force to close the piepline
252+
connect(this, &WaylandCopyClient::dataOfferedNew, this, [pipeFds, this] {
253+
std::lock_guard<std::mutex> guard(PIPELINE_GUARD);
254+
m_pipeIsForcedClosed = true;
255+
close(pipeFds[0]);
256+
});
257+
258+
qint64 offerId = (qint64)offer;
259+
260+
// FIXME: in QtConcurrent run , when signal is emit, sometimes it cannot be recepted
261+
// So sometimes copy will not succcessed
262+
QtConcurrent::run([this, pipeFds, mimeType, offerId] {
263+
QByteArray data;
264+
bool is_successed = readData(pipeFds[0], data);
265+
std::lock_guard<std::mutex> guard(PIPELINE_GUARD);
266+
if (m_pipeIsForcedClosed) {
267+
qDebug() << "pipeline is block here;" << "mimetype is: " << mimeType;
268+
m_pipeIsForcedClosed = false;
269+
return;
270+
}
271+
272+
if (!is_successed) {
273+
qDebug() << "Cannot open pipeline";
274+
return;
275+
}
276+
277+
Q_EMIT dataReady(offerId, mimeType, data);
278+
m_pipeIsForcedClosed = false;
279+
close(pipeFds[0]);
280+
});
281+
282+
}
283+
284+
bool WaylandCopyClient::readData(int fd, QByteArray &data)
285+
{
286+
QFile readPipe;
287+
if (!readPipe.open(fd, QIODevice::ReadOnly)) {
288+
return false;
289+
}
290+
291+
if (!readPipe.isReadable()) {
292+
qWarning() << "Pipe is not readable";
293+
readPipe.close();
294+
return false;
295+
}
296+
297+
int retCount = BYTE_MAX;
298+
do {
299+
QByteArray bytes = readPipe.read(BYTE_MAX);
300+
retCount = bytes.count();
301+
if (!bytes.isEmpty())
302+
data.append(bytes);
303+
} while (retCount == BYTE_MAX);
304+
305+
readPipe.close();
306+
307+
return true;
227308
}
228309

229310
void WaylandCopyClient::taskDataReady(qint64 offer, const QString &mimeType, const QByteArray &data)

dde-clipboard-daemon/waylandcopyclient.h

+5
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class WaylandCopyClient : public QObject
6363
void dataCopied();
6464
// when a new dataOffer request in ,then send it
6565
void dataOfferedNew();
66+
void dataReady(qint64, const QString &, const QByteArray &);
6667

6768
protected slots:
6869
void onSendDataRequest(const QString &mimeType, qint32 fd) const;
@@ -73,6 +74,9 @@ protected slots:
7374
void execTask(const QStringList &mimeTypes, DataControlOfferV1 *offer);
7475
void taskDataReady(qint64, const QString &mimeType, const QByteArray &data);
7576

77+
void onDataOfferedTask(DataControlOfferV1 *offer, const QString &mimeType);
78+
bool readData(int fd, QByteArray &data);
79+
7680
private:
7781
QThread *m_connectionThread;
7882
ConnectionThread *m_connectionThreadObject;
@@ -85,6 +89,7 @@ protected slots:
8589

8690
qint64 m_curOffer;
8791
QStringList m_curMimeTypes;
92+
bool m_pipeIsForcedClosed = false;
8893
};
8994

9095
#endif // COPYCLIENT_H

0 commit comments

Comments
 (0)