https://bugs.kde.org/show_bug.cgi?id=216021

--- Comment #7 from Jiri Palecek <jpale...@web.de> ---
This seems to be a problem with DNSSD::ServiceBrowserPrivate::gotRemoveService
code. It emits a signal and then proceeds to delete some element of the
m_services QList:

     emit m_parent->serviceRemoved(found);
     m_services.removeAll(found);

What happens in Kopete, and particularly its Bonjour code, is that from that
signal, Kopete goes offline and deletes the ServiceBrowser instance. The
control then returns to gotRemovalService, which tries to do the deletion an a
freed object.

The best solution is probably to postpone the deletion of found to the main
loop with QTimer::singleShot, because that can be made so deletion of the
ServiceBrowser object automatically cancels its execution. (I've got a patch
for it, tested and seems to work.) However, I wonder whether in essence all
code that emits signals shouldn't be treated that way, since you don't really
know what happens when the slot connected to the signal executes.

I've also considered if Kopete couldn't be changed so as not to delete the
ServiceBrowser, however, I haven't found a way.

1. Stopping the ServiceBrowser without actually deleting it (and then maybe
restarting it) could work, but I can't see how you could do it.

2. Postponing the deletion to the main loop via ->deleteLater doesn't work,
because it just so happens that the main loop can be nested in kopete. The call
stack looks like this:

(BonjourAccount::disconnect would be called here)
0xaffd45dd in DNSSD::ServiceBrowserPrivate::gotRemoveService (this=0x21ace40,
name=..., type=..., domain=...) at ./dnssd/avahi-servicebrowser.cpp:137
...
0xaffd8a05 in DNSSD::RemoteService::resolve (this=0x21a9e00) at
./dnssd/avahi-remoteservice.cpp:49
0xb006fefe in BonjourAccount::goingOffline (this=0x207abe0, pointer=...) at
./protocols/bonjour/bonjouraccount.cpp:273
...
0xaffd3e01 in DNSSD::ServiceBrowser::serviceRemoved (this=0x21133f0, _t1=...)
at ./obj-i686-linux-gnu/dnssd/servicebrowser.moc:111
0xaffd45c9 in DNSSD::ServiceBrowserPrivate::gotRemoveService (this=0x21ace40,
name=..., type=..., domain=...) at ./dnssd/avahi-servicebrowser.cpp:136

DNSSD::RemoteService::resolve contains an event loop, which means the deferred
deletion would be effective by the time control returns there. The
gotRemoveService sitting up above it in the stack, would be doomed. (Also
tested.) Of course this nested event loop is bad design, but what can you do?

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to