From: Vibhav Pant vibhavp@gmail.com
This frees all associated resources with the watcher, including events and initial devices that were not consumed by the PE driver. --- dlls/winebth.sys/dbus.c | 59 ++++++++++++++++++++++++++++++++------ dlls/winebth.sys/unixlib.c | 1 + 2 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index c911e26550b..f9754309ee5 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -613,6 +613,14 @@ struct bluez_watcher_ctx struct list event_list; };
+struct bluez_init_entry +{ + union { + struct winebluetooth_watcher_event_radio_added radio; + } object; + struct list entry; +}; + void *bluez_dbus_init( void ) { DBusError error; @@ -984,6 +992,47 @@ static const char BLUEZ_MATCH_PROPERTIES[] = "type='signal',"
static const char *BLUEZ_MATCH_RULES[] = { BLUEZ_MATCH_OBJECTMANAGER, BLUEZ_MATCH_PROPERTIES };
+static void bluez_watcher_free( void *data ) +{ + struct bluez_watcher_ctx *watcher = data; + struct bluez_watcher_event *event1, *event2; + struct bluez_init_entry *entry1, *entry2; + + if (watcher->init_device_list_call) + { + p_dbus_pending_call_cancel( watcher->init_device_list_call ); + p_dbus_pending_call_unref( watcher->init_device_list_call ); + } + + LIST_FOR_EACH_ENTRY_SAFE( entry1, entry2, &watcher->initial_radio_list, struct bluez_init_entry, entry ) + { + list_remove( &entry1->entry ); + unix_name_free( (struct unix_name *)entry1->object.radio.radio.handle ); + free( entry1 ); + } + + LIST_FOR_EACH_ENTRY_SAFE( event1, event2, &watcher->event_list, struct bluez_watcher_event, entry ) + { + list_remove( &event1->entry ); + switch (event1->event_type) + { + case BLUETOOTH_WATCHER_EVENT_TYPE_RADIO_ADDED: + unix_name_free( (struct unix_name *)event1->event.radio_added.radio.handle ); + break; + case BLUETOOTH_WATCHER_EVENT_TYPE_RADIO_REMOVED: + unix_name_free( (struct unix_name *)event1->event.radio_removed.handle ); + break; + case BLUETOOTH_WATCHER_EVENT_TYPE_RADIO_PROPERTIES_CHANGED: + unix_name_free( (struct unix_name *)event1->event.radio_props_changed.radio.handle ); + break; + } + free( event1 ); + } + + pthread_mutex_destroy( &watcher->event_lists_lock ); + free( watcher ); +} + NTSTATUS bluez_watcher_init( void *connection, void **ctx ) { DBusError err; @@ -1007,7 +1056,7 @@ NTSTATUS bluez_watcher_init( void *connection, void **ctx )
list_init( &watcher_ctx->event_list );
- if (!p_dbus_connection_add_filter( connection, bluez_filter, watcher_ctx, free )) + if (!p_dbus_connection_add_filter( connection, bluez_filter, watcher_ctx, bluez_watcher_free )) { p_dbus_pending_call_cancel( call ); p_dbus_pending_call_unref( call ); @@ -1056,14 +1105,6 @@ void bluez_watcher_close( void *connection, void *ctx ) p_dbus_connection_remove_filter( connection, bluez_filter, ctx ); }
-struct bluez_init_entry -{ - union { - struct winebluetooth_watcher_event_radio_added radio; - } object; - struct list entry; -}; - static NTSTATUS bluez_build_initial_device_lists( DBusMessage *reply, struct list *adapter_list ) { DBusMessageIter dict, paths_iter, iface_iter, prop_iter; diff --git a/dlls/winebth.sys/unixlib.c b/dlls/winebth.sys/unixlib.c index e42707ce3ba..28d12f1e2e0 100644 --- a/dlls/winebth.sys/unixlib.c +++ b/dlls/winebth.sys/unixlib.c @@ -114,6 +114,7 @@ static NTSTATUS bluetooth_shutdown( void *params ) { if (!dbus_connection) return STATUS_NOT_SUPPORTED;
+ bluez_watcher_close( dbus_connection, bluetooth_watcher ); bluez_dbus_close( dbus_connection ); bluez_dbus_free( dbus_connection ); return STATUS_SUCCESS;