-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Murmur: fix bad interaction with QDBus and fork(). #2821
Conversation
e0c9748
to
5ebe478
Compare
src/murmur/DBus.h
Outdated
@@ -103,6 +103,12 @@ struct LogEntry { | |||
Q_DECLARE_METATYPE(LogEntry); | |||
Q_DECLARE_METATYPE(QList<LogEntry>); | |||
|
|||
class MurmurDBusConnectionHolder { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not quite seeing the point of MurmurDBusConnectionHolder. The way it is written it seems we can copy construct QDBusConnection so why not use a QDBusConnection* directly? If we do not care about the precise timing of the cleanup we can make it a smart pointer and don't have to care about cleanup either. Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I just wanted to avoid having to deref a pointer qdbc directly (*qdbc) in the QDBusInterface constructors... I'll try.
@@ -511,29 +511,29 @@ int main(int argc, char **argv) { | |||
|
|||
if (! Meta::mp.qsDBus.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not something for this issue but we should think about moving that initialization code into the DBus specific file. main is bloated enough as it is.
There's also something broken where when running w/o dbus enabled. I get a crash. |
5ebe478
to
a3e1fd5
Compare
@hacst PTAL |
Qt 5.6 changed QDBus to use a thread, QDBusConnectionManager, for managing DBus connections. This caused a bad interaction with Murmur. It turns out that, prior to this commit, the QDBusConnectionManager in Murmur was launched at program start, because of a global static QDBusConnection in DBus.cpp. This meant that there would be a QDBusConnectionManager thread around, waiting to manage DBus connections. ...Until Murmur calls fork(). After fork()ing, the QDBusConnectionManager thread is gone -- fork only keeps a 'main' thread, and isn't generally compatible with multi-threaded programs. Ouch! Fortunately, the static global QDBusConnection (MurmurDBus::qdbc) was only initialized this way because it worked in the past. Also, because QDBusConnection has no default constructor, the 'qdbc' QDBusConnection was statically initialized as a QDBusConnection to 'mainbus' on each program launch. This wasn't strictly necessary -- it was only done because QDBusConnection had no default constructor. However, there is no such thing as an 'empty' QDBusConnection, so there not being a default constructor does make sense. To avoid the static global QDBusConnection, this commit changes MurmuDBus::qdbc from a value to a pointer. This allows us to defer the creation of the QDBusConnectionManager thread until the first 'real' QDBusConnection is created -- after Murmur has forked. This avoids the global static 'fake' QDBusConnection, and ensures the QDBusConnectionManager thread is created after Murmur has forked. Additionally, this commit also moves the registration of the 'MetaDBus' object into the '!Meta::mp.qsDBus.isEmpty()' check in main.cpp. This ensures the MetaDBus object is only registered if the user has enabled DBus in murmur.ini. Without this change, the code would be dereferencing a null MurmurDBus::qdbc. Fixes mumble-voip#2820
a3e1fd5
to
1e9d2b3
Compare
OK, added another paragraph to the commit message about the move of MetaDBus registration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Qt 5.6 changed QDBus to use a thread, QDBusConnectionManager for
DBus connections.
This caused a bad interaction with Murmur. It turns out that, prior
to this commit, the QDBusConnectionManager in Murmur was launched at
program start, because of a global static QDBusConnection in DBus.cpp.
This meant that there would be a QDBusConnectionManager thread around,
waiting to manage DBus connections. ...Until Murmur calls fork().
After fork()ing, the QDBusConnectionManager thread is gone -- fork only
keeps a 'main' thread, and isn't generally compatible with multi-threaded
programs.
Ouch!
Fortunately, the static global QDBusConnection (MurmurDBus::qdbc) was
only initialized this way because it worked in the past. Also, because
QDBusConnection has no default constructor, the 'qdbc' QDBusConnection
was statically initialized as a QDBusConnection to 'mainbus' on each
program launch. This wasn't strictly necessary -- it was only done because
QDBusConnection had no default constructor. However, there is no such thing
as an 'empty' QDBusConnection, so there not being a default constructor
does make sense.
To avoid the static global QDBusConnection, this change introduces a
new type: MurmurDBusConnectionHolder. It's a global static as well,
but it's a pointer that holds a concrete QDBusConnection.
This allows us to defer the creation of the QDBusConnectionManager thread
until the first 'real' QDBusConnection is created -- after Murmur has forked.
This avoids the global static 'fake' QDBusConnection, and ensures the
QDBusConnectionManager thread is created after Murmur has forked.
Fixes #2820