KDE 4.11 showstopper: KMix lockup for 20 seconds, and a concept for fixing it
Harald Sitter
sitter.harald at gmail.com
Thu Jul 11 10:12:50 BST 2013
Ahoy,
On Thu, Jul 11, 2013 at 12:35 AM, Christian Esken <esken at kde.org> wrote:
> Here is some background information on what is happening:
> MPRIS2 is using DBUS. I finally I got the notion that doing DBUS requests is
> evil - at least ANY synchronous DBUS communication. I am pretty sure I am
> not the first with these problems, so if anybody has working code that shows
> how to do it I would be glad. Or review my concept code.
This is not limited to dbus but really any syncronous interaction
through IPC is bad. Just like synchronous interactiong between threads
is bad, what with processes just being fancy threads from an OS point
of view ;).
There is luckily a couple of things that can be changed without
turning to threads and perhaps one or all of them will help improve
the situation.
First I must super highly extremly absolutely recommend generating a
c++/qt version of the dbus interface derived from
qdbusabstractinterface [1]. This will make the code much cleaner and
easier to use as you do not have to constantly fiddle with QVariants
and the likes.
For example go into kde:kde-workspace/plasma/generic/dataengines/mpris2 and run
> qdbusxml2cpp -p player org.mpris.MediaPlayer2.Player.xml
There will now be player.cpp and player.h reflecting an interface to
org.mpris.MediaPlayer2.Player. If you take a look at the q_slots (i.e.
dbus functions) you'll notice that this interface is already ready for
async usage.
To see how all of this comes together I suggest a look at the
dataengine's CMake and/or source (although the dataengine also has to
map plasma's job architecture to mpris, so that may be more confusing
than helpful). Implementing this approach will allow you easier usage
of dbus, less likely failure and in may help to render QThread usage
unnecessary.
Secondly whatever your concern/complaint with using async
communication by means of slotting the dbuspendingcalls may be
QDbusPendingCallWatcher [2] can probably help you handle the signals.
Or perhaps QSignalMapper [3] is something more appropriate.
Thirdly after having briefly looked through the proposed QThread
change I would highly advise against it.The implementation is
basically reimplementating Qt (messageQueueThreadLoop -> QEventLoop;
message -> QEvent;) this would be twice as readable code if it simply
added 2 slots.
> public Q_SLOTS:
> void plug();
> void quit();
which you'd call with
> QMetaObject::invokeMethod(thread, "plug");
or if you are feeling fancy you'd add associated signals and do
> emit triggerThreadedPluging;
However short of seralizing the pluging through that messageloop thing
(which btw is doing very efficient polling - not) the thread does
absolutely nothing; the deadlock/timeout is still there. If you plug
clementine, amarok and tomahawk in that order, it will take 25+
seconds until amarok is actually plugged because clementine will still
timeout and will until then block the thread, then if amarok also
times out it will take 50+ seconds until tomahawk gets plugged......
All in all it appears to me the thread solves nothing and might only
cause problems in the future (as threads tend to do).
[1] http://techbase.kde.org/Development/Tutorials/D-Bus/Accessing_Interfaces#Using_Classes_Generated_From_D-Bus_XML
[2] https://qt-project.org/doc/qt-4.8/qdbuspendingcallwatcher.html
[3] https://qt-project.org/doc/qt-4.8/qsignalmapper.html
HS
More information about the kde-multimedia
mailing list