Skip to content

fix: add X connection monitoring for session logout#199

Open
mhduiy wants to merge 1 commit intolinuxdeepin:masterfrom
mhduiy:xwatch
Open

fix: add X connection monitoring for session logout#199
mhduiy wants to merge 1 commit intolinuxdeepin:masterfrom
mhduiy:xwatch

Conversation

@mhduiy
Copy link
Contributor

@mhduiy mhduiy commented Mar 21, 2026

Added XCB dependency and implemented X server connection monitoring to detect when the X server disconnects. This ensures the session properly logs out when the X server connection is lost, preventing orphaned sessions.

  1. Added libxcb1-dev to Build-Depends in debian/control
  2. Added XCB pkg-config check and linking in CMakeLists.txt
  3. Implemented watchXConnection() method that establishes an XCB connection and monitors the file descriptor using QSocketNotifier
  4. When X connection errors are detected, the session automatically triggers logout to clean up resources
  5. Only activates on X11 displays, not Wayland

This fix addresses cases where X server crashes or disconnects unexpectedly, leaving the session manager running without a display server.

fix: 添加X连接监控以实现会话登出

添加XCB依赖并实现X服务器连接监控,以检测X服务器断开连接的情况。这确保当X
服务器连接丢失时会话能正确登出,防止出现孤儿会话。

  1. 在debian/control的Build-Depends中添加libxcb1-dev
  2. 在CMakeLists.txt中添加XCB pkg-config检查和链接
  3. 实现watchXConnection()方法,使用XCB建立连接并通过QSocketNotifier监控 文件描述符
  4. 当检测到X连接错误时,会话自动触发登出以清理资源
  5. 仅在X11显示环境下激活,Wayland环境下不启用

此修复解决了X服务器崩溃或意外断开连接时,会话管理器在没有显示服务器的情
况下继续运行的问题。

PMS: BUG-353461

Summary by Sourcery

Monitor the X server connection in the session manager and trigger logout when the X connection is lost on X11 displays.

Bug Fixes:

  • Ensure the session manager logs out automatically when the X server disconnects or crashes to avoid orphaned sessions on X11.

Enhancements:

  • Introduce X connection monitoring in SessionManager using a socket notifier, enabled only for non-Wayland displays.

Build:

  • Add XCB as a pkg-config dependency and link it into the dde-session target.
  • Add libxcb development dependency to the Debian packaging metadata.

Added XCB dependency and implemented X server connection monitoring to
detect when the X server disconnects. This ensures the session properly
logs out when the X server connection is lost, preventing orphaned
sessions.

1. Added libxcb1-dev to Build-Depends in debian/control
2. Added XCB pkg-config check and linking in CMakeLists.txt
3. Implemented watchXConnection() method that establishes an XCB
connection and monitors the file descriptor using QSocketNotifier
4. When X connection errors are detected, the session automatically
triggers logout to clean up resources
5. Only activates on X11 displays, not Wayland

This fix addresses cases where X server crashes or disconnects
unexpectedly, leaving the session manager running without a display
server.

fix: 添加X连接监控以实现会话登出

添加XCB依赖并实现X服务器连接监控,以检测X服务器断开连接的情况。这确保当X
服务器连接丢失时会话能正确登出,防止出现孤儿会话。

1. 在debian/control的Build-Depends中添加libxcb1-dev
2. 在CMakeLists.txt中添加XCB pkg-config检查和链接
3. 实现watchXConnection()方法,使用XCB建立连接并通过QSocketNotifier监控
文件描述符
4. 当检测到X连接错误时,会话自动触发登出以清理资源
5. 仅在X11显示环境下激活,Wayland环境下不启用

此修复解决了X服务器崩溃或意外断开连接时,会话管理器在没有显示服务器的情
况下继续运行的问题。

PMS: BUG-353461
@deepin-ci-robot
Copy link

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mhduiy

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai
Copy link

sourcery-ai bot commented Mar 21, 2026

Reviewer's Guide

Implements X11 connection monitoring in the session manager using libxcb and QSocketNotifier so that when the X server disconnects, the session manager detects the error and triggers a logout, with corresponding build system and packaging updates for the new XCB dependency.

Sequence diagram for X server disconnect triggering session logout

sequenceDiagram
    participant SessionManager
    participant XCBConnection
    participant QSocketNotifier
    participant XServer

    SessionManager->>SessionManager: init()
    alt not Utils_IS_WAYLAND_DISPLAY
        SessionManager->>SessionManager: watchXConnection()
        SessionManager->>XCBConnection: xcb_connect()
        XCBConnection-->>SessionManager: connection handle and fd
        SessionManager->>QSocketNotifier: create with fd and Read
        SessionManager->>QSocketNotifier: connect activated signal
    end

    XServer--x XCBConnection: disconnect or crash
    XCBConnection-->>QSocketNotifier: fd becomes readable
    QSocketNotifier-->>SessionManager: activated(fd, Read)

    SessionManager->>XCBConnection: xcb_poll_for_event() loop
    SessionManager->>XCBConnection: xcb_connection_has_error()
    alt connection has error
        SessionManager->>QSocketNotifier: setEnabled(false)
        SessionManager->>XCBConnection: xcb_disconnect()
        SessionManager->>SessionManager: doLogout()
    else no error
        SessionManager-->>QSocketNotifier: continue monitoring
    end
Loading

Updated class diagram for SessionManager with X connection monitoring

classDiagram
    class SessionManager {
        +init() void
        +watchXConnection() void
        +handleOSSignal() void
        +shutdown(bool force) void
        +reboot(bool force) void
        +setDPMSMode(bool on) void
        +doLogout() void
    }
Loading

File-Level Changes

Change Details Files
Add X11 connection monitoring in SessionManager to trigger logout when the X server disconnects.
  • Introduce watchXConnection() in SessionManager that opens an xcb connection and monitors its file descriptor with QSocketNotifier
  • On QSocketNotifier activation, drain pending X events with xcb_poll_for_event and check xcb_connection_has_error
  • When an X connection error is detected, disable the notifier, disconnect from X, and call doLogout()
  • Invoke watchXConnection() during SessionManager::init() only when not running on a Wayland display
src/dde-session/impl/sessionmanager.cpp
src/dde-session/impl/sessionmanager.h
Wire in the new XCB dependency into the build and packaging configuration.
  • Add pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb) and link PkgConfig::XCB into the dde-session target
  • Update SPDX copyright header year range in dde-session CMakeLists
  • Declare libxcb1-dev as a build dependency in debian/control
src/dde-session/CMakeLists.txt
debian/control

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot
Copy link

deepin pr auto review

这段代码主要实现了在非 Wayland 环境下监听 X Server 连接状态的功能,当 X Server 连接断开时触发登出操作。以下是对该代码的详细审查和改进建议:

1. 语法与逻辑审查

  • 逻辑正确性
    • xcb_connect(nullptr, nullptr):逻辑正确。传入 nullptr 会使用 DISPLAY 环境变量,符合预期。
    • xcb_poll_for_event 循环:逻辑正确。在 Qt 事件循环触发 Socket 可读时,必须排空 XCB 的队列,否则 Socket 会一直处于可读状态导致死循环(Busy Loop)。
    • xcb_connection_has_error 检查:逻辑正确。这是检测 X Server 断开的标准方法。
  • 语法
    • C++ 语法和 Qt 信号槽连接语法均无误。

2. 代码质量与规范

  • 头文件包含
    • sessionmanager.cpp 中增加了 #include <QSocketNotifier>#include <xcb/xcb.h>,这是必要的。
  • 版权年份
    • CMakeLists.txt 中的版权年份从 2023 修改为 2023 - 2026。这通常是合理的,表示维护周期的预期,但需确认是否符合项目规范。
  • 内存管理
    • new QSocketNotifier(...) 创建在堆上,且指定了 this 作为父对象。Qt 的对象树机制会确保在 SessionManager 析构时自动删除该对象,符合 Qt 内存管理规范
  • 注释
    • // 排空所有待处理事件// 若连接已断开则触发登出 注释清晰,有助于理解代码意图。

3. 代码性能

  • 事件排空效率
    • while ((ev = xcb_poll_for_event(conn)) != nullptr) 循环是必要的。虽然看起来是在循环处理,但它是在消耗掉缓冲区中的数据,防止 QSocketNotifier 频繁触发,实际上避免了性能浪费。
  • 资源占用
    • 增加了一个 XCB 连接和一个文件描述符监听,资源开销极小,对性能影响可忽略不计。

4. 代码安全

  • 潜在的内存泄漏风险

    • 问题点:在 watchXConnection 函数中,如果 xcb_connection_has_error(conn) 检测到错误,代码执行了 xcb_disconnect(conn) 并返回。但是,之前创建的 notifier 对象(new QSocketNotifier)并没有被显式删除或禁用。
    • 后果:虽然 notifier 的父对象是 this,最终会被析构,但在 watchXConnection 返回后,该 notifier 对象仍然存活且处于启用状态。如果此时 fd 变为可读(由于连接断开或系统行为),activated 信号可能会被触发,导致访问已断开或无效的 conn 指针,引发 段错误(Segmentation Fault) 或未定义行为。
    • 改进建议:在连接失败或断开时,应确保 notifier 被禁用或删除。
  • 竞态条件

    • 问题点xcb_connectxcb_get_file_descriptor 之间,或者 xcb_poll_for_eventxcb_connection_has_error 之间,理论上存在极微小的竞态窗口。但在实际应用中,X Server 的断开通常是相对"慢"的事件,且 xcb_poll_for_event 本身会检查错误,这种风险在单线程 Qt 事件循环模型下较低。
    • 改进建议:保持现状即可,现有逻辑已经足够健壮。
  • 空指针解引用

    • 代码中检查了 xcb_connection_has_error,确保 conn 有效后才使用 xcb_get_file_descriptor,安全性良好。

5. 改进后的代码建议

针对上述提到的安全风险(主要是 notifier 对象的生命周期管理),建议对 watchXConnection 进行如下微调:

void SessionManager::watchXConnection()
{
    xcb_connection_t *conn = xcb_connect(nullptr, nullptr);
    if (xcb_connection_has_error(conn) || !conn) {
        qWarning() << "watchXConnection: failed to connect to X server";
        if (conn) xcb_disconnect(conn);
        return;
    }

    int fd = xcb_get_file_descriptor(conn);
    auto *notifier = new QSocketNotifier(fd, QSocketNotifier::Read, this);
    
    // 使用 trackConnection 确保在 lambda 中安全捕获
    // 使用 QPointer 防止悬垂指针(虽然 notifier 父对象是 this,但为了更严谨的代码习惯)
    QPointer<QSocketNotifier> safeNotifier = notifier;

    connect(notifier, &QSocketNotifier::activated, this, [=]() {
        // 如果 notifier 已经被标记为删除或无效,直接返回
        if (!safeNotifier) return;

        // 排空所有待处理事件
        xcb_generic_event_t *ev;
        while ((ev = xcb_poll_for_event(conn)) != nullptr) {
            free(ev);
        }

        // 若连接已断开则触发登出
        if (xcb_connection_has_error(conn)) {
            qWarning() << "X connection closed, logging out";
            // 立即禁用 notifier 防止重复触发
            if (safeNotifier) {
                safeNotifier->setEnabled(false);
                safeNotifier->deleteLater(); // 安全地标记删除
            }
            xcb_disconnect(conn);
            doLogout();
        }
    });
}

总结

这段代码整体质量不错,逻辑清晰,能够解决检测 X Server 断开的问题。主要需要改进的地方是在错误处理路径上加强对 QSocketNotifier 对象的管理,防止在连接失效后继续触发回调导致访问无效内存。此外,依赖项的添加是合理且必要的。

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants