fix: Separate DConfig object creation to another thread to avoid blocking#548
fix: Separate DConfig object creation to another thread to avoid blocking#548zccrs merged 1 commit intolinuxdeepin:masterfrom
Conversation
|
Hi @apr3vau. 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 GuideThis PR avoids blocking the main thread by moving DConfig setup into a background context via a dconfig2cpp-generated wrapper, synchronizing initialization with a QEventLoop and signals; it also updates the CMake build to generate and include the wrapper header and adjusts packaging dependencies accordingly. Sequence diagram for asynchronous DConfig initialization in TreelandConfigsequenceDiagram
participant TreelandConfig
participant dconfig_org_deepin_treeland
participant QEventLoop
TreelandConfig->>dconfig_org_deepin_treeland: createByName()
TreelandConfig->>QEventLoop: connect initialized signal
dconfig_org_deepin_treeland-->>TreelandConfig: configInitializeSucceed signal
TreelandConfig->>TreelandConfig: Assign DConfig and read values
TreelandConfig->>TreelandConfig: emit initialized()
TreelandConfig->>QEventLoop: quit()
QEventLoop->>QEventLoop: exec() (waits for initialized)
TreelandConfig->>DConfig: connect valueChanged signal
Class diagram for updated TreelandConfig and dconfig_org_deepin_treeland integrationclassDiagram
class TreelandConfig {
+initialized()
-dconfig_org_deepin_treeland *
-std::unique_ptr<DConfig> m_dconfig
-uint m_maxWorkspace
-uint m_numWorkspace
-uint m_currentWorkspace
-bool m_forceSoftwareCursor
-QString m_activeColor
-float m_windowRadius
-QString m_cursorThemeName
-QSize m_cursorSize
-uint m_windowOpacity
-uint m_windowThemeType
-uint m_windowTitlebarHeight
-QString m_fontName
-QString m_monoFontName
-uint m_fontSize
-QString m_iconThemeName
-QString m_defaultBackground
+onDConfigChanged(key: QString)
}
class dconfig_org_deepin_treeland {
+createByName(name: QString, service: QString, path: QString)
+configInitializeSucceed
+config(): DConfig*
}
TreelandConfig --> dconfig_org_deepin_treeland : uses
TreelandConfig --> DConfig : owns
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey there - I've reviewed your changes and found some issues that need to be addressed.
Blocking issues:
- Blocking the constructor with QEventLoop may cause deadlocks or UI freezes. (link)
General comments:
- Consider adding error handling for config initialization failures (e.g., handling the configInitializeFailed signal) to avoid the event loop hanging indefinitely if initialization fails.
- Avoid blocking in the constructor with a QEventLoop—consider exposing asynchronous initialization or using a factory method to initialize TreelandConfig, which can improve responsiveness and avoid potential deadlocks.
- Rather than storing the raw pointer m_dconfig_org_deepin_treeland, consider transferring ownership with a smart pointer (e.g., QScopedPointer or std::unique_ptr) to ensure proper cleanup and avoid memory leaks.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider adding error handling for config initialization failures (e.g., handling the configInitializeFailed signal) to avoid the event loop hanging indefinitely if initialization fails.
- Avoid blocking in the constructor with a QEventLoop—consider exposing asynchronous initialization or using a factory method to initialize TreelandConfig, which can improve responsiveness and avoid potential deadlocks.
- Rather than storing the raw pointer m_dconfig_org_deepin_treeland, consider transferring ownership with a smart pointer (e.g., QScopedPointer or std::unique_ptr) to ensure proper cleanup and avoid memory leaks.
## Individual Comments
### Comment 1
<location> `src/config/treelandconfig.cpp:16` </location>
<code_context>
+ QEventLoop eventLoop;
</code_context>
<issue_to_address>
Blocking the constructor with QEventLoop may cause deadlocks or UI freezes.
Blocking the main thread in a constructor with QEventLoop::exec() risks deadlocks and UI unresponsiveness. Refactor to initialize asynchronously or defer setup until after construction.
</issue_to_address>
### Comment 2
<location> `src/config/treelandconfig.cpp:44` </location>
<code_context>
+ });
+ eventLoop.exec();
+
connect(m_dconfig.get(), &DConfig::valueChanged, this, &TreelandConfig::onDConfigChanged);
}
</code_context>
<issue_to_address>
Connecting to m_dconfig before it is initialized may cause runtime errors.
If configInitializeSucceed is not emitted, m_dconfig remains null, which can cause a crash. Please ensure m_dconfig is valid before connecting, or add a guard to prevent this issue.
</issue_to_address>
### Comment 3
<location> `src/config/treelandconfig.cpp:40` </location>
<code_context>
+ m_fontSize = m_dconfig->value("fontSize", 105).toUInt();
+ m_iconThemeName = m_dconfig->value("iconThemeName").toString();
+ m_defaultBackground = m_dconfig->value("defaultBackground").toString();
+ Q_EMIT initialized();
+ });
+ eventLoop.exec();
</code_context>
<issue_to_address>
Emitting initialized() inside a lambda may cause reentrancy issues.
Consider emitting the signal after object construction or adding safeguards to prevent slots from accessing the object before it is fully initialized.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
bb4e496 to
0da3db9
Compare
0da3db9 to
796d461
Compare
…king DConfig object creation involves D-Bus communication, which may block when placed in the main thread. This commit adapt dconfig2cpp tool to generate DConfig wrapper safely running in another thread, to avoid this problem.
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: apr3vau, zccrs 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 |
DConfig object creation involves D-Bus communication, which may block when placed in the main thread. This commit adapt dconfig2cpp tool to generate DConfig wrapper safely running in another thread, to avoid this problem.
更新:彻底删除旧的TreelandConfig封装类,将dconfig2cpp生成的类命名为TreelandConfig取而代之。同时将旧有的与工作区相关的本地配置单独拆分为WorkspaceConfig。
Summary by Sourcery
Prevent blocking in the main thread during DConfig creation by moving initialization into a worker thread via a DConfig wrapper generated at build time and synchronously waiting for readiness.
Enhancements:
Build:
Chores: