X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/66f04c3bdcbdd550d8a7ce0486251bf1d502fb3a..eca082a93f2619cfa10733947a81fa779cb49573:/src/pulsecore/protocol-dbus.c diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c index 6a0dcf34..cf4b9fc5 100644 --- a/src/pulsecore/protocol-dbus.c +++ b/src/pulsecore/protocol-dbus.c @@ -57,15 +57,15 @@ struct connection_entry { DBusConnection *connection; pa_client *client; - pa_bool_t listening_for_all_signals; + bool listening_for_all_signals; /* Contains object paths. If this is empty, then signals from all objects - * are accepted. Only used when listening_for_all_signals == TRUE. */ + * are accepted. Only used when listening_for_all_signals == true. */ pa_idxset *all_signals_objects; /* Signal name -> signal paths entry. The entries contain object paths. If * a path set is empty, then that signal is accepted from all objects. This - * variable is only used when listening_for_all_signals == FALSE. */ + * variable is only used when listening_for_all_signals == false. */ pa_hashmap *listening_signals; }; @@ -169,9 +169,9 @@ void pa_dbus_protocol_unref(pa_dbus_protocol *p) { pa_assert(pa_hashmap_isempty(p->connections)); pa_assert(pa_idxset_isempty(p->extensions)); - pa_hashmap_free(p->objects, NULL, NULL); - pa_hashmap_free(p->connections, NULL, NULL); - pa_idxset_free(p->extensions, NULL, NULL); + pa_hashmap_free(p->objects); + pa_hashmap_free(p->connections); + pa_idxset_free(p->extensions, NULL); for (i = 0; i < PA_DBUS_PROTOCOL_HOOK_MAX; ++i) pa_hook_done(&p->hooks[i]); @@ -360,7 +360,7 @@ static enum find_result_t find_handler_by_method(struct call_info *call_info) { PA_HASHMAP_FOREACH(call_info->iface_entry, call_info->obj_entry->interfaces, state) { if ((call_info->method_handler = pa_hashmap_get(call_info->iface_entry->method_handlers, call_info->method))) { - call_info->expected_method_sig = pa_hashmap_get(call_info->iface_entry->method_signatures, call_info->method); + pa_assert_se(call_info->expected_method_sig = pa_hashmap_get(call_info->iface_entry->method_signatures, call_info->method)); if (pa_streq(call_info->method_sig, call_info->expected_method_sig)) return FOUND_METHOD; @@ -468,10 +468,15 @@ static enum find_result_t find_handler(struct call_info *call_info) { else if (!(call_info->iface_entry = pa_hashmap_get(call_info->obj_entry->interfaces, call_info->interface))) return NO_SUCH_INTERFACE; - else if ((call_info->method_handler = pa_hashmap_get(call_info->iface_entry->method_handlers, call_info->method))) + else if ((call_info->method_handler = pa_hashmap_get(call_info->iface_entry->method_handlers, call_info->method))) { + pa_assert_se(call_info->expected_method_sig = pa_hashmap_get(call_info->iface_entry->method_signatures, call_info->method)); + + if (!pa_streq(call_info->method_sig, call_info->expected_method_sig)) + return INVALID_METHOD_SIG; + return FOUND_METHOD; - else + } else return NO_SUCH_METHOD; } else { /* The method call doesn't contain an interface. */ @@ -628,6 +633,23 @@ static pa_dbus_arg_info *copy_args(const pa_dbus_arg_info *src, unsigned n) { return dst; } +static void method_handler_free(pa_dbus_method_handler *h) { + unsigned i; + + pa_assert(h); + + pa_xfree((char *) h->method_name); + + for (i = 0; i < h->n_arguments; ++i) { + pa_xfree((char *) h->arguments[i].name); + pa_xfree((char *) h->arguments[i].type); + pa_xfree((char *) h->arguments[i].direction); + } + + pa_xfree((pa_dbus_arg_info *) h->arguments); + pa_xfree(h); +} + static pa_hashmap *create_method_handlers(const pa_dbus_interface_info *info) { pa_hashmap *handlers; unsigned i; @@ -635,7 +657,7 @@ static pa_hashmap *create_method_handlers(const pa_dbus_interface_info *info) { pa_assert(info); pa_assert(info->method_handlers || info->n_method_handlers == 0); - handlers = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + handlers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) method_handler_free); for (i = 0; i < info->n_method_handlers; ++i) { pa_dbus_method_handler *h = pa_xnew(pa_dbus_method_handler, 1); @@ -644,7 +666,7 @@ static pa_hashmap *create_method_handlers(const pa_dbus_interface_info *info) { h->n_arguments = info->method_handlers[i].n_arguments; h->receive_cb = info->method_handlers[i].receive_cb; - pa_hashmap_put(handlers, h->method_name, h); + pa_hashmap_put(handlers, (char *) h->method_name, h); } return handlers; @@ -659,7 +681,7 @@ static pa_hashmap *extract_method_signatures(pa_hashmap *method_handlers) { pa_assert(method_handlers); - signatures = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + signatures = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, pa_xfree); PA_HASHMAP_FOREACH(handler, method_handlers, state) { sig_buf = pa_strbuf_new(); @@ -669,12 +691,21 @@ static pa_hashmap *extract_method_signatures(pa_hashmap *method_handlers) { pa_strbuf_puts(sig_buf, handler->arguments[i].type); } - pa_hashmap_put(signatures, handler->method_name, pa_strbuf_tostring_free(sig_buf)); + pa_hashmap_put(signatures, (char *) handler->method_name, pa_strbuf_tostring_free(sig_buf)); } return signatures; } +static void property_handler_free(pa_dbus_property_handler *h) { + pa_assert(h); + + pa_xfree((char *) h->property_name); + pa_xfree((char *) h->type); + + pa_xfree(h); +} + static pa_hashmap *create_property_handlers(const pa_dbus_interface_info *info) { pa_hashmap *handlers; unsigned i = 0; @@ -682,7 +713,7 @@ static pa_hashmap *create_property_handlers(const pa_dbus_interface_info *info) pa_assert(info); pa_assert(info->property_handlers || info->n_property_handlers == 0); - handlers = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + handlers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) property_handler_free); for (i = 0; i < info->n_property_handlers; ++i) { pa_dbus_property_handler *h = pa_xnew(pa_dbus_property_handler, 1); @@ -691,7 +722,7 @@ static pa_hashmap *create_property_handlers(const pa_dbus_interface_info *info) h->get_cb = info->property_handlers[i].get_cb; h->set_cb = info->property_handlers[i].set_cb; - pa_hashmap_put(handlers, h->property_name, h); + pa_hashmap_put(handlers, (char *) h->property_name, h); } return handlers; @@ -725,7 +756,7 @@ int pa_dbus_protocol_add_interface(pa_dbus_protocol *p, void *userdata) { struct object_entry *obj_entry; struct interface_entry *iface_entry; - pa_bool_t obj_entry_created = FALSE; + bool obj_entry_created = false; pa_assert(p); pa_assert(path); @@ -743,7 +774,7 @@ int pa_dbus_protocol_add_interface(pa_dbus_protocol *p, obj_entry->introspection = NULL; pa_hashmap_put(p->objects, obj_entry->path, obj_entry); - obj_entry_created = TRUE; + obj_entry_created = true; } if (pa_hashmap_get(obj_entry->interfaces, info->name) != NULL) @@ -784,41 +815,6 @@ static void unregister_object(pa_dbus_protocol *p, struct object_entry *obj_entr pa_assert_se(dbus_connection_unregister_object_path(conn_entry->connection, obj_entry->path)); } -static void method_handler_free_cb(void *p, void *userdata) { - pa_dbus_method_handler *h = p; - unsigned i; - - pa_assert(h); - - pa_xfree((char *) h->method_name); - - for (i = 0; i < h->n_arguments; ++i) { - pa_xfree((char *) h->arguments[i].name); - pa_xfree((char *) h->arguments[i].type); - pa_xfree((char *) h->arguments[i].direction); - } - - pa_xfree((pa_dbus_arg_info *) h->arguments); - pa_xfree(h); -} - -static void method_signature_free_cb(void *p, void *userdata) { - pa_assert(p); - - pa_xfree(p); -} - -static void property_handler_free_cb(void *p, void *userdata) { - pa_dbus_property_handler *h = p; - - pa_assert(h); - - pa_xfree((char *) h->property_name); - pa_xfree((char *) h->type); - - pa_xfree(h); -} - int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, const char* interface) { struct object_entry *obj_entry; struct interface_entry *iface_entry; @@ -839,9 +835,9 @@ int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, con pa_log_debug("Interface %s removed from object %s", iface_entry->name, obj_entry->path); pa_xfree(iface_entry->name); - pa_hashmap_free(iface_entry->method_signatures, method_signature_free_cb, NULL); - pa_hashmap_free(iface_entry->method_handlers, method_handler_free_cb, NULL); - pa_hashmap_free(iface_entry->property_handlers, property_handler_free_cb, NULL); + pa_hashmap_free(iface_entry->method_signatures); + pa_hashmap_free(iface_entry->method_handlers); + pa_hashmap_free(iface_entry->property_handlers); for (i = 0; i < iface_entry->n_signals; ++i) { unsigned j; @@ -865,7 +861,7 @@ int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, con pa_hashmap_remove(p->objects, path); pa_xfree(obj_entry->path); - pa_hashmap_free(obj_entry->interfaces, NULL, NULL); + pa_hashmap_free(obj_entry->interfaces); pa_xfree(obj_entry->introspection); pa_xfree(obj_entry); } @@ -884,6 +880,14 @@ static void register_all_objects(pa_dbus_protocol *p, DBusConnection *conn) { pa_assert_se(dbus_connection_register_object_path(conn, obj_entry->path, &vtable, p)); } +static void signal_paths_entry_free(struct signal_paths_entry *e) { + pa_assert(e); + + pa_xfree(e->signal); + pa_idxset_free(e->paths, pa_xfree); + pa_xfree(e); +} + int pa_dbus_protocol_register_connection(pa_dbus_protocol *p, DBusConnection *conn, pa_client *client) { struct connection_entry *conn_entry; @@ -899,9 +903,10 @@ int pa_dbus_protocol_register_connection(pa_dbus_protocol *p, DBusConnection *co conn_entry = pa_xnew(struct connection_entry, 1); conn_entry->connection = dbus_connection_ref(conn); conn_entry->client = client; - conn_entry->listening_for_all_signals = FALSE; + conn_entry->listening_for_all_signals = false; conn_entry->all_signals_objects = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - conn_entry->listening_signals = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + conn_entry->listening_signals = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, + (pa_free_cb_t) signal_paths_entry_free); pa_hashmap_put(p->connections, conn, conn_entry); @@ -931,24 +936,8 @@ static struct signal_paths_entry *signal_paths_entry_new(const char *signal_name return e; } -static void signal_paths_entry_free(struct signal_paths_entry *e) { - char *path = NULL; - - pa_assert(e); - - pa_xfree(e->signal); - - while ((path = pa_idxset_steal_first(e->paths, NULL))) - pa_xfree(path); - - pa_idxset_free(e->paths, NULL, NULL); - pa_xfree(e); -} - int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *conn) { struct connection_entry *conn_entry = NULL; - struct signal_paths_entry *signal_paths_entry = NULL; - char *object_path = NULL; pa_assert(p); pa_assert(conn); @@ -959,16 +948,8 @@ int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection * unregister_all_objects(p, conn); dbus_connection_unref(conn_entry->connection); - - while ((object_path = pa_idxset_steal_first(conn_entry->all_signals_objects, NULL))) - pa_xfree(object_path); - - pa_idxset_free(conn_entry->all_signals_objects, NULL, NULL); - - while ((signal_paths_entry = pa_hashmap_steal_first(conn_entry->listening_signals))) - signal_paths_entry_free(signal_paths_entry); - - pa_hashmap_free(conn_entry->listening_signals, NULL, NULL); + pa_idxset_free(conn_entry->all_signals_objects, pa_xfree); + pa_hashmap_free(conn_entry->listening_signals); pa_xfree(conn_entry); return 0; @@ -994,7 +975,6 @@ void pa_dbus_protocol_add_signal_listener( unsigned n_objects) { struct connection_entry *conn_entry = NULL; struct signal_paths_entry *signal_paths_entry = NULL; - char *object_path = NULL; unsigned i = 0; pa_assert(p); @@ -1005,17 +985,15 @@ void pa_dbus_protocol_add_signal_listener( /* all_signals_objects will either be emptied or replaced with new objects, * so we empty it here unconditionally. If listening_for_all_signals is - * currently FALSE, the idxset is empty already so this does nothing. */ - while ((object_path = pa_idxset_steal_first(conn_entry->all_signals_objects, NULL))) - pa_xfree(object_path); + * currently false, the idxset is empty already so this does nothing. */ + pa_idxset_remove_all(conn_entry->all_signals_objects, pa_xfree); if (signal_name) { - conn_entry->listening_for_all_signals = FALSE; + conn_entry->listening_for_all_signals = false; /* Replace the old signal paths entry for this signal with a new * one. */ - if ((signal_paths_entry = pa_hashmap_remove(conn_entry->listening_signals, signal_name))) - signal_paths_entry_free(signal_paths_entry); + pa_hashmap_remove_and_free(conn_entry->listening_signals, signal_name); signal_paths_entry = signal_paths_entry_new(signal_name); for (i = 0; i < n_objects; ++i) @@ -1024,12 +1002,11 @@ void pa_dbus_protocol_add_signal_listener( pa_hashmap_put(conn_entry->listening_signals, signal_paths_entry->signal, signal_paths_entry); } else { - conn_entry->listening_for_all_signals = TRUE; + conn_entry->listening_for_all_signals = true; /* We're not interested in individual signals anymore, so let's empty * listening_signals. */ - while ((signal_paths_entry = pa_hashmap_steal_first(conn_entry->listening_signals))) - signal_paths_entry_free(signal_paths_entry); + pa_hashmap_remove_all(conn_entry->listening_signals); for (i = 0; i < n_objects; ++i) pa_idxset_put(conn_entry->all_signals_objects, pa_xstrdup(objects[i]), NULL); @@ -1046,19 +1023,13 @@ void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection pa_assert_se((conn_entry = pa_hashmap_get(p->connections, conn))); if (signal_name) { - if ((signal_paths_entry = pa_hashmap_get(conn_entry->listening_signals, signal_name))) + if ((signal_paths_entry = pa_hashmap_remove(conn_entry->listening_signals, signal_name))) signal_paths_entry_free(signal_paths_entry); } else { - char *object_path; - - conn_entry->listening_for_all_signals = FALSE; - - while ((object_path = pa_idxset_steal_first(conn_entry->all_signals_objects, NULL))) - pa_xfree(object_path); - - while ((signal_paths_entry = pa_hashmap_steal_first(conn_entry->listening_signals))) - signal_paths_entry_free(signal_paths_entry); + conn_entry->listening_for_all_signals = false; + pa_idxset_remove_all(conn_entry->all_signals_objects, pa_xfree); + pa_hashmap_remove_all(conn_entry->listening_signals); } }