Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialise DBus notifications in another thread #152

Closed
wants to merge 1 commit into from

Conversation

luke-jr
Copy link
Member

@luke-jr luke-jr commented Dec 14, 2020

QDBusInterface's constructor can hang if org.freedesktop.Notifications is missing, so avoid delaying startup waiting for a timeout

interface->moveToThread(m_notificator.thread());
m_notificator.interface = interface;
m_notificator.mode = Notificator::Freedesktop;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Emit finished here and clean up instead of keeping the thread for the Notificator lifecycle? DBusInitThread name implies it's disposable as soon as init is done.

Copy link
Member Author

Choose a reason for hiding this comment

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

Isn't that supposed to be an automatic part of Qt? The docs say the user can't emit it...

Copy link
Contributor

Choose a reason for hiding this comment

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

You're right. I think it used to be public signal but seems that is no longer the case.

Choose a reason for hiding this comment

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

I'd say move m_dbus_init_thread->wait(); call into ~DBusInitThread(), so it no longer can be possible to misuse (forget). Also, connecting finished() signal could perform cleanup:

m_dbus_init_thread = new DBusInitThread(*this);
connect(m_dbus_init_thread, &DBusInitThread::finished, this, [this]() {
   m_dbus_init_thread->deleteLater();
   m_dbus_init_thread = nullptr;
});
m_dbus_init_thread->start();

@hebasto
Copy link
Member

hebasto commented Jan 10, 2021

QDBusInterface's constructor can hang if org.freedesktop.Notifications is missing

Qt docs says:

If the remote service service is not present ..., the object created will not be valid...

QDBusInterface's constructor can hang if org.freedesktop.Notifications is missing, so avoid delaying startup waiting for a timeout
Copy link

@Talkless Talkless left a comment

Choose a reason for hiding this comment

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

Concept ACK.

interface->moveToThread(m_notificator.thread());
m_notificator.interface = interface;
m_notificator.mode = Notificator::Freedesktop;
}

Choose a reason for hiding this comment

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

I'd say move m_dbus_init_thread->wait(); call into ~DBusInitThread(), so it no longer can be possible to misuse (forget). Also, connecting finished() signal could perform cleanup:

m_dbus_init_thread = new DBusInitThread(*this);
connect(m_dbus_init_thread, &DBusInitThread::finished, this, [this]() {
   m_dbus_init_thread->deleteLater();
   m_dbus_init_thread = nullptr;
});
m_dbus_init_thread->start();

QDBusInterface *interface;
friend class DBusInitThread;

Choose a reason for hiding this comment

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

friend could be avoided if DBusInitThread would have interfaceCreated(QDBusInterface* interface) signal.

Signal can be invoked from within run() using:

QTimer::singelShot(0, this, [this, interface]() {
  emit interfaceCreated(interface);
});

singleShot will detect that this (context) lives in different thread and lambda will be invoked in that (receiver) context thread (where DBusInitThread was created).

In the result, std::atomic<Mode> mode; "atomicity" will not be needed, because

  this->interface = interface;
  mode = Notificator::Freedesktop;

..would be performed on thread Notificator lives, within a slot (or just lambda) that connected to the DBusInitThread::interfaceCreated(QDBusInterface*) signal, and so without any race condition, as we are setting two variables, and only one is atomic.

DBusInitThread constructor will have to get QThread* though for moveToThread().. Or jus use DBusInitThread::thread() to get that "destination" thread? But that's might break if interface-receiving thread is not the same that created DBusInitThread object...

Also, adding interface->setParent(this) after this->interface = interface; would remove need for manual delete, unless there's deletion ordering is involved...

@DrahtBot
Copy link
Contributor

DrahtBot commented Apr 6, 2022

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline for information on the review process.

Type Reviewers
Concept ACK Talkless

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #686 (clang-tidy: Force checks for headers in src/qt by hebasto)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@hebasto hebasto changed the title GUI: Initialise DBus notifications in another thread Initialise DBus notifications in another thread Apr 15, 2022
@hebasto
Copy link
Member

hebasto commented May 19, 2022

A related discussion on IRC:

<luke-jr> oh, I guess Core never merged the dbus timeout fix - that's probably why -qt is slower
<luke-jr> #152
<hebasto> luke-jr: it is not obvious that bug exist, in first place -- #152 (comment)
<luke-jr> hebasto: it definitely exists
<hebasto> how to reproduce it reliably?
<luke-jr> idk, happens every time for me
<luke-jr> maybe running bitcoin-qt as another user?
<hebasto> ok, could you describe your steps and observations in your PR?
<luke-jr> there's no steps, it just happens
<hebasto> at least, you could mention your system on which "org.freedesktop.Notifications is missing"

@DrahtBot
Copy link
Contributor

🐙 This pull request conflicts with the target branch and needs rebase.

@DrahtBot
Copy link
Contributor

There hasn't been much activity lately and the patch still needs rebase. What is the status here?

  • Is it still relevant? ➡️ Please solve the conflicts to make it ready for review and to ensure the CI passes.
  • Is it no longer relevant? ➡️ Please close.
  • Did the author lose interest or time to work on this? ➡️ Please close it and mark it 'Up for grabs' with the label, so that it can be picked up in the future.

@hebasto
Copy link
Member

hebasto commented Apr 17, 2023

Closing this due to lack of activity. Feel free to reopen.

@hebasto hebasto closed this Apr 17, 2023
@bitcoin-core bitcoin-core locked and limited conversation to collaborators Apr 16, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants