Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: LFRon The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @LFRon. Thanks for your PR. 😃 |
|
Hi @LFRon. Thanks for your PR. I'm waiting for a linuxdeepin member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Reviewer's GuideFixes large clipboard transfers to XWayland clients by fully writing payloads to non-blocking selection pipes, with bounded retry/error handling and safer asynchronous data preparation; exact stored image MIME payloads are now returned without unnecessary re-encoding. Sequence diagram for reliable large clipboard transfersequenceDiagram
participant XWayland as XWayland client
participant Compositor as Compositor pipe
participant Clipboard as Clipboard daemon
participant Worker as Write worker
XWayland->>Compositor: Request clipboard MIME data
Compositor->>Clipboard: onSourceSend(mimeType, fd)
Clipboard->>Clipboard: getByteArray(mMimeData, mimeType)
Clipboard->>Worker: QtConcurrent::run(data, fd)
loop Until all bytes are written
Worker->>Compositor: write(fd, remaining data)
alt Pipe accepts bytes
Compositor-->>Worker: Short or complete write
else EAGAIN
Worker->>Compositor: poll(fd, POLLOUT)
Compositor-->>Worker: Pipe writable
end
end
Worker-->>XWayland: Complete clipboard payload
Flow diagram for exact image payload selectionflowchart TD
A[Request image MIME type] --> B{Stored exact MIME payload available?}
B -->|Yes| C[Return original stored bytes]
B -->|No| D[Read imageData from QMimeData]
D --> E[Encode with QImageWriter]
C --> F[Write payload to clipboard pipe]
E --> F
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="dde-clipboard-daemon/wlrintegration/wlrdatacontrolclipboardinterface.cpp" line_range="364-370" />
<code_context>
+ // Linux has no MSG_NOSIGNAL for pipes; block SIGPIPE around the
+ // write instead. pthread_sigmask is used because this runs on a
+ // worker thread of a thread pool.
+ sigset_t blocked, previous;
+ sigemptyset(&blocked);
+ sigaddset(&blocked, SIGPIPE);
+ pthread_sigmask(SIG_BLOCK, &blocked, &previous);
+ const ssize_t written = ::write(fd, pos, count);
+ const int savedErrno = errno;
+ pthread_sigmask(SIG_SETMASK, &previous, nullptr);
+ errno = savedErrno;
+ return written;
</code_context>
<issue_to_address>
**issue (bug_risk):** Blocking SIGPIPE during `write()` does not consume the signal generated when the peer has closed the pipe. Restoring the previous unblocked mask delivers the pending SIGPIPE immediately, so the daemon still terminates instead of treating a requestor-aborted transfer as a normal write failure.
**Triggers:** When the compositor or clipboard requestor closes the read end while a worker is writing.
**Suggested fix:** Use `SIG_IGN` with restoration, consume a pending SIGPIPE before unblocking it, or use an equivalent pipe-safe mechanism such as handling SIGPIPE explicitly and checking `EPIPE`.
```suggestion
sigset_t blocked, previous;
sigemptyset(&blocked);
sigaddset(&blocked, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &blocked, &previous);
const ssize_t written = ::write(fd, pos, count);
const int savedErrno = errno;
if (written < 0 && savedErrno == EPIPE) {
sigset_t pending;
if (sigpending(&pending) == 0
&& sigismember(&pending, SIGPIPE) == 1) {
int signalNumber;
sigwait(&blocked, &signalNumber);
}
}
pthread_sigmask(SIG_SETMASK, &previous, nullptr);
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| sigset_t blocked, previous; | ||
| sigemptyset(&blocked); | ||
| sigaddset(&blocked, SIGPIPE); | ||
| pthread_sigmask(SIG_BLOCK, &blocked, &previous); | ||
| const ssize_t written = ::write(fd, pos, count); | ||
| const int savedErrno = errno; | ||
| pthread_sigmask(SIG_SETMASK, &previous, nullptr); |
There was a problem hiding this comment.
issue (bug_risk): Blocking SIGPIPE during write() does not consume the signal generated when the peer has closed the pipe. Restoring the previous unblocked mask delivers the pending SIGPIPE immediately, so the daemon still terminates instead of treating a requestor-aborted transfer as a normal write failure.
Triggers: When the compositor or clipboard requestor closes the read end while a worker is writing.
Suggested fix: Use SIG_IGN with restoration, consume a pending SIGPIPE before unblocking it, or use an equivalent pipe-safe mechanism such as handling SIGPIPE explicitly and checking EPIPE.
| sigset_t blocked, previous; | |
| sigemptyset(&blocked); | |
| sigaddset(&blocked, SIGPIPE); | |
| pthread_sigmask(SIG_BLOCK, &blocked, &previous); | |
| const ssize_t written = ::write(fd, pos, count); | |
| const int savedErrno = errno; | |
| pthread_sigmask(SIG_SETMASK, &previous, nullptr); | |
| sigset_t blocked, previous; | |
| sigemptyset(&blocked); | |
| sigaddset(&blocked, SIGPIPE); | |
| pthread_sigmask(SIG_BLOCK, &blocked, &previous); | |
| const ssize_t written = ::write(fd, pos, count); | |
| const int savedErrno = errno; | |
| if (written < 0 && savedErrno == EPIPE) { | |
| sigset_t pending; | |
| if (sigpending(&pending) == 0 | |
| && sigismember(&pending, SIGPIPE) == 1) { | |
| int signalNumber; | |
| sigwait(&blocked, &signalNumber); | |
| } | |
| } | |
| pthread_sigmask(SIG_SETMASK, &previous, nullptr); |
06d546e to
c071101
Compare
|
TAG Bot New tag: 6.1.35 |
The compositor hands out O_NONBLOCK pipe ends for selection transfers and paces large transfers (X11 INCR) by pausing reads, so a naive QFile::write() stopped at the first EAGAIN after only ~64 KiB. Large payloads such as screenshots reached XWayland clients truncated: images showed partially decoded content with garbled bands and failed to send, while Wayland clients using blocking offer pipes were unaffected. - Add writeDataToPipe() which resumes after short writes, waits for writability on EAGAIN via poll(), suppresses SIGPIPE around each write and bounds the whole write with a 30s deadline so a stalled reader can never wedge the write thread pool. - Evaluate the requested payload on the owning thread and pass the implicitly-shared QByteArray to the worker; check write results, log failures and guard against a null m_mimeData by closing the fd. - Serve stored raw bytes for exact image MIME requests instead of re-encoding through QImageWriter, which changed the payload size and cost a full decode+encode round trip per request; keep the re-encoding fallback for entries without stored bytes (history replay). 修复向非阻塞选区管道回传大数据被截断的问题。 合成器为选区传输下发的管道两端为 O_NONBLOCK,并依靠暂停读取对大传输(X11 INCR)节流;原先一次朴素的 QFile::write 在首次 EAGAIN 时即停止,仅送出约 64KiB。截图等大 payload 到达 XWayland 客户端时被截断,表现为图片只有部分 解码内容并出现花屏条带、发送失败;使用阻塞 offer 管道的 Wayland 客户端 不受影响。 - 新增 writeDataToPipe():短写后继续写,EAGAIN 时用 poll() 等待可写,每次 write 周围屏蔽 SIGPIPE,并以 30 秒超时兜底,读取方卡死不会永久占用写 线程池。 - 在所属线程求值请求数据,将隐式共享的 QByteArray 交给工作线程;检查写入 结果并记录日志;对空的 m_mimeData 判空并关闭 fd,避免空指针解引用。 - 精确匹配的图片 MIME 请求优先返回已存储的原始字节,不再经 QImageWriter 重编码(避免 payload 尺寸变化和每请求一次完整解码+编码的开销);无存储 字节的条目(历史回放)保留原有重编码回退。 Log: avoid truncating large clipboard payloads on non-blocking pipes
c071101 to
c97bf03
Compare
该PR修复了: 在treeland环境下, 走DDE内置的截图软件/xdg-desktop-portal-dde -> treeland截图时, 如果截图的图像体积太大, 复制到Xwayland跑的QQ/微信等软件上会被截成一块一块的而且最后报错发送失败
修复向非阻塞选区管道回传大数据被截断的问题。
合成器为选区传输下发的管道两端为 O_NONBLOCK,并依靠暂停读取对大传输(X11
INCR)节流;原先一次朴素的 QFile::write 在首次 EAGAIN 时即停止,仅送出约
64KiB。截图等大 payload 到达 XWayland 客户端时被截断,表现为图片只有部分
解码内容并出现花屏条带、发送失败;使用阻塞 offer 管道的 Wayland 客户端
不受影响。
Log: avoid truncating large clipboard payloads on non-blocking pipes
Summary by Sourcery
Ensure reliable delivery of large clipboard payloads through non-blocking pipes while preserving original image data when possible.
Bug Fixes:
Enhancements: