On 10 November 2012 05:25, Ian Malone <ibmalone at gmail.com> wrote: > On 9 November 2012 17:34, Tanu Kaskinen <tanuk at iki.fi> wrote: >> On Tue, 2012-11-06 at 15:58 -0500, Ian Malone wrote: >>> method call sender=:1.110 -> >>> dest=org.freedesktop.ReserveDevice1.Audio1 serial=6 >>> path=/org/freedesktop/ReserveDevice1/Audio1; >>> interface=org.freedesktop.ReserveDevice1; member=RequestRelease >>> int32 2147483647 >>> error sender=:1.35 -> dest=:1.110 >>> error_name=org.freedesktop.DBus.Error.UnknownMethod reply_serial=6 >>> string "Method "RequestRelease" with signature "i" on interface >>> "org.freedesktop.ReserveDevice1" doesn't exist >>> " >> > If I hadn't seen it before I would say that that's exactly the message > I expect a message framework (d-bus here) to generate when the method > wasn't present. And indeed it is: > $ dbus-send --session --print-reply --reply-timeout=2000 > --type=method_call --dest=org.freedesktop.ReserveDevice1.Audio1 > /org/freedesktop/ReserveDevice1/Audio1 > org.freedesktop.ReserveDevice1.RequestRelease int32:5 > Error org.freedesktop.DBus.Error.UnknownMethod: Method > "RequestRelease" with signature "i" on interface > "org.freedesktop.ReserveDevice1" doesn't exist > > I don't know how to capture this at the command line, so please see > the d-feet shot of this: > > https://picasaweb.google.com/lh/photo/Mnty0Ul3ilCN_pB-ctJoD9MTjNZETYmyPJy0liipFm0?feat=directlink > > Audio1 is reserved (the service exists), but the object to request a > release for Audio1 doesn't exist. Getting to this state was actually > quite easy: > 1. Start into KDE (pulse is set up as normal for Fedora and autostarted). > 2. Start d-feet, you may catch the ReserveDevice1 services before they > disappear, but wait till they do. > 3. Open the KDE audio setup dialogue and test playback, this causes > pulse to lock the capture device (hw:0 here) and the playback device > (hw:1). > 4. Look at the 'reserved' services. Audio1 is reserved, but can't be > released because there's no object to provide the method. > ======= --- a/src/modules/reserve.c +++ b/src/modules/reserve.c @@ -409,6 +409,11 @@ int rd_acquire( goto fail; } + if (k == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) { + // Potential leak? + goto success; + } + if (k == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) goto success; ======= It seems rd_acquire can get called while pulse still has the service name (how? don't know. I've tried a return 0 there, but the object path has already been unregistered at that point). Currently that means it unregisters the filter handler and the object path for releasedevice1, turning the service into a zombie until pulse is killed. I've tried fixing this by changing the way d->owning is used, but anything but the current setup seems to get stuck in a loop between rd_callback, the filter_handler in reserve.c and rd_release, possibly because unregistering the service triggers the filter_handler with namelost somehow. Anyway, thou shalt check for possible return values. -- imalone http://ibmalone.blogspot.co.uk