fix avahi service browser destruction

without keeping track of the avahi service resolvers and
destroying them when the parent object goes away, callbacks
might be called after after the dhe destruction and passing
an invalid userdata pointer.
This commit is contained in:
Michael Zanetti 2017-07-06 17:05:28 +02:00
parent 3ed80c2766
commit ac179d0f70
2 changed files with 17 additions and 4 deletions

View File

@ -35,6 +35,13 @@ QtAvahiServiceBrowserPrivate::QtAvahiServiceBrowserPrivate(QtAvahiClient *client
}
QtAvahiServiceBrowserPrivate::~QtAvahiServiceBrowserPrivate()
{
foreach (AvahiServiceResolver *resolver, m_serviceResolvers) {
avahi_service_resolver_free(resolver);
}
}
void QtAvahiServiceBrowserPrivate::callbackServiceTypeBrowser(AvahiServiceTypeBrowser *browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *type, const char *domain, AvahiLookupResultFlags flags, void *userdata)
{
Q_UNUSED(browser)
@ -79,9 +86,9 @@ void QtAvahiServiceBrowserPrivate::callbackServiceBrowser(AvahiServiceBrowser *b
return;
switch (event) {
case AVAHI_BROWSER_NEW:
case AVAHI_BROWSER_NEW: {
// Start resolving new service
if (!(avahi_service_resolver_new(serviceBrowser->d_ptr->client->client,
AvahiServiceResolver *resolver = avahi_service_resolver_new(serviceBrowser->d_ptr->client->client,
interface,
protocol,
name,
@ -90,11 +97,14 @@ void QtAvahiServiceBrowserPrivate::callbackServiceBrowser(AvahiServiceBrowser *b
AVAHI_PROTO_UNSPEC,
(AvahiLookupFlags) 0,
QtAvahiServiceBrowserPrivate::callbackServiceResolver,
serviceBrowser))) {
serviceBrowser);
if (resolver) {
serviceBrowser->d_ptr->m_serviceResolvers.append(resolver);
} else {
qCWarning(dcAvahi()) << "Failed to resolve service" << QString(name) << ":" << avahi_strerror(avahi_client_errno(serviceBrowser->d_ptr->client->client));
}
break;
}
case AVAHI_BROWSER_REMOVE: {
// Remove the service
foreach (const AvahiServiceEntry &entry, serviceBrowser->m_serviceEntries) {
@ -166,6 +176,7 @@ void QtAvahiServiceBrowserPrivate::callbackServiceResolver(AvahiServiceResolver
emit serviceBrowser->serviceEntryAdded(entry);
}
}
serviceBrowser->d_ptr->m_serviceResolvers.removeAll(resolver);
avahi_service_resolver_free(resolver);
}

View File

@ -35,6 +35,7 @@ class LIBGUH_EXPORT QtAvahiServiceBrowserPrivate
{
public:
QtAvahiServiceBrowserPrivate(QtAvahiClient *client);
~QtAvahiServiceBrowserPrivate();
// Callback members
static void callbackServiceTypeBrowser(AvahiServiceTypeBrowser *browser,
@ -76,6 +77,7 @@ public:
QtAvahiClient *client;
AvahiServiceTypeBrowser *serviceTypeBrowser;
QHash<QString, AvahiServiceBrowser *> serviceBrowserTable;
QList<AvahiServiceResolver *> m_serviceResolvers;
};
#endif // QTAVAHISERVICEBROWSERPRIVATE_H