diff options
author | Colin Guthrie <cguthrie@mandriva.org> | 2010-06-05 18:21:31 +0100 |
---|---|---|
committer | Colin Guthrie <cguthrie@mandriva.org> | 2010-06-05 18:21:31 +0100 |
commit | 1415a295c25d331985c2e9a2a387ba0edd89ea0f (patch) | |
tree | 1e225a2350d47b9e0b79572546a432b04c60de70 | |
parent | 3df68451010ff1f374cffbb325b7346640365152 (diff) | |
parent | 22a8c4485be336267b44f72336af859f80014c09 (diff) |
Merge remote branch 'tanuk2/fixes'
-rw-r--r-- | src/modules/alsa/alsa-mixer.c | 4 | ||||
-rw-r--r-- | src/modules/alsa/alsa-sink.c | 5 | ||||
-rw-r--r-- | src/modules/alsa/alsa-source.c | 5 | ||||
-rw-r--r-- | src/modules/dbus/module-dbus-protocol.c | 61 | ||||
-rw-r--r-- | src/modules/module-stream-restore.c | 5 | ||||
-rw-r--r-- | src/pulsecore/cli-command.c | 2 | ||||
-rw-r--r-- | src/pulsecore/protocol-dbus.c | 118 |
7 files changed, 118 insertions, 82 deletions
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c index 93f2ed055..b2888a360 100644 --- a/src/modules/alsa/alsa-mixer.c +++ b/src/modules/alsa/alsa-mixer.c @@ -1037,7 +1037,7 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) { e->switch_use = PA_ALSA_SWITCH_IGNORE; e->volume_use = PA_ALSA_VOLUME_IGNORE; - e->enumeration_use = PA_ALSA_VOLUME_IGNORE; + e->enumeration_use = PA_ALSA_ENUMERATION_IGNORE; return 0; } @@ -2683,7 +2683,7 @@ static int mapping_parse_description( pa_assert(ps); if ((m = mapping_get(ps, section))) { - pa_xstrdup(m->description); + pa_xfree(m->description); m->description = pa_xstrdup(rvalue); } else if ((p = profile_get(ps, section))) { pa_xfree(p->description); diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index ce7970b23..35a806c84 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1252,10 +1252,7 @@ static int sink_set_port_cb(pa_sink *s, pa_device_port *p) { s->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB); s->n_volume_steps = PA_VOLUME_NORM+1; - if (u->mixer_path->max_dB > 0.0) - pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(s->base_volume)); - else - pa_log_info("No particular base volume set, fixing to 0 dB"); + pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(s->base_volume)); } else { s->base_volume = PA_VOLUME_NORM; s->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1; diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 00810c86c..381a7062b 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1186,10 +1186,7 @@ static int source_set_port_cb(pa_source *s, pa_device_port *p) { s->base_volume = pa_sw_volume_from_dB(-u->mixer_path->max_dB); s->n_volume_steps = PA_VOLUME_NORM+1; - if (u->mixer_path->max_dB > 0.0) - pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(s->base_volume)); - else - pa_log_info("No particular base volume set, fixing to 0 dB"); + pa_log_info("Fixing base volume to %0.2f dB", pa_sw_volume_to_dB(s->base_volume)); } else { s->base_volume = PA_VOLUME_NORM; s->n_volume_steps = u->mixer_path->max_volume - u->mixer_path->min_volume + 1; diff --git a/src/modules/dbus/module-dbus-protocol.c b/src/modules/dbus/module-dbus-protocol.c index acc6ca045..aa11cdfcf 100644 --- a/src/modules/dbus/module-dbus-protocol.c +++ b/src/modules/dbus/module-dbus-protocol.c @@ -48,13 +48,12 @@ PA_MODULE_DESCRIPTION("D-Bus interface"); PA_MODULE_USAGE( "access=local|remote|local,remote " - "tcp_port=<port number>"); + "tcp_port=<port number> " + "tcp_listen=<hostname>"); PA_MODULE_LOAD_ONCE(TRUE); PA_MODULE_AUTHOR("Tanu Kaskinen"); PA_MODULE_VERSION(PACKAGE_VERSION); -#define CLEANUP_INTERVAL 10 /* seconds */ - enum server_type { SERVER_TYPE_LOCAL, SERVER_TYPE_TCP @@ -68,13 +67,14 @@ struct userdata { pa_bool_t local_access; pa_bool_t remote_access; uint32_t tcp_port; + char *tcp_listen; struct server *local_server; struct server *tcp_server; pa_idxset *connections; - pa_time_event *cleanup_event; + pa_defer_event *cleanup_event; pa_dbus_protocol *dbus_protocol; pa_dbusiface_core *core_iface; @@ -95,6 +95,7 @@ struct connection { static const char* const valid_modargs[] = { "access", "tcp_port", + "tcp_listen", NULL }; @@ -154,6 +155,23 @@ static dbus_bool_t user_check_cb(DBusConnection *connection, unsigned long uid, return TRUE; } +static DBusHandlerResult disconnection_filter_cb(DBusConnection *connection, DBusMessage *message, void *user_data) { + struct connection *c = user_data; + + pa_assert(connection); + pa_assert(message); + pa_assert(c); + + if (dbus_message_is_signal(message, "org.freedesktop.DBus.Local", "Disconnected")) { + /* The connection died. Now we want to free the connection object, but + * let's wait until this message is fully processed, in case someone + * else is interested in this signal too. */ + c->server->userdata->module->core->mainloop->defer_enable(c->server->userdata->cleanup_event, 1); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + /* Called by D-Bus when a new client connection is received. */ static void connection_new_cb(DBusServer *dbus_server, DBusConnection *new_connection, void *data) { struct server *s = data; @@ -192,6 +210,8 @@ static void connection_new_cb(DBusServer *dbus_server, DBusConnection *new_conne c->client->send_event = client_send_event_cb; c->client->userdata = c; + pa_assert_se(dbus_connection_add_filter(new_connection, disconnection_filter_cb, c, NULL)); + pa_idxset_put(s->userdata->connections, c, NULL); pa_assert_se(pa_dbus_protocol_register_connection(s->userdata->dbus_protocol, new_connection, c->client) >= 0); @@ -401,6 +421,7 @@ static struct server *start_server(struct userdata *u, const char *address, enum s = pa_xnew0(struct server, 1); s->userdata = u; + s->type = type; s->dbus_server = dbus_server_listen(address, &error); if (dbus_error_is_set(&error)) { @@ -452,7 +473,7 @@ static struct server *start_tcp_server(struct userdata *u) { pa_assert(u); - address = pa_sprintf_malloc("tcp:host=127.0.0.1,port=%u", u->tcp_port); + address = pa_sprintf_malloc("tcp:host=%s,port=%u", u->tcp_listen, u->tcp_port); s = start_server(u, address, SERVER_TYPE_TCP); /* May return NULL */ @@ -486,33 +507,23 @@ static int get_access_arg(pa_modargs *ma, pa_bool_t *local_access, pa_bool_t *re return 0; } -/* Frees dead client connections. Called every CLEANUP_INTERVAL seconds. */ -static void cleanup_cb(pa_mainloop_api *a, pa_time_event *e, const struct timeval *tv, void *userdata) { +/* Frees dead client connections. */ +static void cleanup_cb(pa_mainloop_api *a, pa_defer_event *e, void *userdata) { struct userdata *u = userdata; struct connection *conn = NULL; uint32_t idx; - struct timeval cleanup_timeval; - unsigned free_count = 0; - for (conn = pa_idxset_first(u->connections, &idx); conn; conn = pa_idxset_next(u->connections, &idx)) { - if (!dbus_connection_get_is_connected(pa_dbus_wrap_connection_get(conn->wrap_conn))) { + PA_IDXSET_FOREACH(conn, u->connections, idx) { + if (!dbus_connection_get_is_connected(pa_dbus_wrap_connection_get(conn->wrap_conn))) connection_free(conn); - ++free_count; - } } - if (free_count > 0) - pa_log_debug("Freed %u dead D-Bus client connections.", free_count); - - pa_gettimeofday(&cleanup_timeval); - cleanup_timeval.tv_sec += CLEANUP_INTERVAL; - u->module->core->mainloop->time_restart(e, &cleanup_timeval); + u->module->core->mainloop->defer_enable(e, 0); } int pa__init(pa_module *m) { struct userdata *u = NULL; pa_modargs *ma = NULL; - struct timeval cleanup_timeval; pa_assert(m); @@ -537,6 +548,8 @@ int pa__init(pa_module *m) { goto fail; } + u->tcp_listen = pa_xstrdup(pa_modargs_get_value(ma, "tcp_listen", "0.0.0.0")); + if (u->local_access && !(u->local_server = start_local_server(u))) { pa_log("Starting the local D-Bus server failed."); goto fail; @@ -549,9 +562,8 @@ int pa__init(pa_module *m) { u->connections = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - pa_gettimeofday(&cleanup_timeval); - cleanup_timeval.tv_sec += CLEANUP_INTERVAL; - u->cleanup_event = m->core->mainloop->time_new(m->core->mainloop, &cleanup_timeval, cleanup_cb, u); + u->cleanup_event = m->core->mainloop->defer_new(m->core->mainloop, cleanup_cb, u); + m->core->mainloop->defer_enable(u->cleanup_event, 0); u->dbus_protocol = pa_dbus_protocol_get(m->core); u->core_iface = pa_dbusiface_core_new(m->core); @@ -588,7 +600,7 @@ void pa__done(pa_module *m) { pa_dbusiface_core_free(u->core_iface); if (u->cleanup_event) - m->core->mainloop->time_free(u->cleanup_event); + m->core->mainloop->defer_free(u->cleanup_event); if (u->connections) pa_idxset_free(u->connections, connection_free_cb, NULL); @@ -602,6 +614,7 @@ void pa__done(pa_module *m) { if (u->dbus_protocol) pa_dbus_protocol_unref(u->dbus_protocol); + pa_xfree(u->tcp_listen); pa_xfree(u); m->userdata = NULL; } diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c index c16a74c34..346b6ad12 100644 --- a/src/modules/module-stream-restore.c +++ b/src/modules/module-stream-restore.c @@ -310,7 +310,7 @@ static struct dbus_entry *dbus_entry_new(struct userdata *u, const char *entry_n de->index = u->next_index++; de->object_path = pa_sprintf_malloc("%s/%s%u", OBJECT_PATH, ENTRY_OBJECT_NAME, de->index); - pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, de->object_path, &entry_interface_info, u) >= 0); + pa_assert_se(pa_dbus_protocol_add_interface(u->dbus_protocol, de->object_path, &entry_interface_info, de) >= 0); return de; } @@ -765,6 +765,7 @@ static void handle_entry_set_device(DBusConnection *conn, DBusMessage *msg, DBus value.size = sizeof(struct entry); pa_assert_se(pa_database_set(de->userdata->database, &key, &value, TRUE) == 0); + apply_entry(de->userdata, de->entry_name, e); send_device_updated_signal(de, e); trigger_save(de->userdata); } @@ -829,6 +830,7 @@ static void handle_entry_set_volume(DBusConnection *conn, DBusMessage *msg, DBus value.size = sizeof(struct entry); pa_assert_se(pa_database_set(de->userdata->database, &key, &value, TRUE) == 0); + apply_entry(de->userdata, de->entry_name, e); send_volume_updated_signal(de, e); trigger_save(de->userdata); } @@ -886,6 +888,7 @@ static void handle_entry_set_mute(DBusConnection *conn, DBusMessage *msg, DBusMe value.size = sizeof(struct entry); pa_assert_se(pa_database_set(de->userdata->database, &key, &value, TRUE) == 0); + apply_entry(de->userdata, de->entry_name, e); send_mute_updated_signal(de, e); trigger_save(de->userdata); } diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 82a44d84e..a5497d9db 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -1766,7 +1766,7 @@ int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, pa_bo } int pa_cli_command_execute_file_stream(pa_core *c, FILE *f, pa_strbuf *buf, pa_bool_t *fail) { - char line[1024]; + char line[2048]; int ifstate = IFSTATE_NONE; int ret = -1; pa_bool_t _fail = TRUE; diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c index 582bc6583..13c05d922 100644 --- a/src/pulsecore/protocol-dbus.c +++ b/src/pulsecore/protocol-dbus.c @@ -63,12 +63,18 @@ struct connection_entry { * are accepted. Only used when listening_for_all_signals == TRUE. */ pa_idxset *all_signals_objects; - /* Signal name -> idxset. The idxsets contain object paths. If an idxset is - * empty, then that signal is accepted from all objects. Only used when - * listening_for_all_signals == FALSE. */ + /* 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. */ pa_hashmap *listening_signals; }; +/* Only used in connection entries' listening_signals hashmap. */ +struct signal_paths_entry { + char *signal; + pa_idxset *paths; +}; + struct interface_entry { char *name; pa_hashmap *method_handlers; @@ -406,7 +412,7 @@ static enum find_result_t find_handler_from_properties_call(struct call_info *ca return NO_SUCH_PROPERTY_INTERFACE; else if ((call_info->property_handler = pa_hashmap_get(call_info->iface_entry->property_handlers, call_info->property))) - return FOUND_GET_PROPERTY; + return call_info->property_handler->get_cb ? FOUND_GET_PROPERTY : PROPERTY_ACCESS_DENIED; else return NO_SUCH_PROPERTY; @@ -440,7 +446,7 @@ static enum find_result_t find_handler_from_properties_call(struct call_info *ca call_info->expected_property_sig = call_info->property_handler->type; if (pa_streq(call_info->property_sig, call_info->expected_property_sig)) - return FOUND_SET_PROPERTY; + return call_info->property_handler->set_cb ? FOUND_SET_PROPERTY : PROPERTY_ACCESS_DENIED; else return INVALID_PROPERTY_SIG; @@ -919,22 +925,35 @@ static void unregister_all_objects(pa_dbus_protocol *p, DBusConnection *conn) { pa_assert_se(dbus_connection_unregister_object_path(conn, obj_entry->path)); } -static void free_listened_object_name_cb(void *p, void *userdata) { - pa_assert(p); +static struct signal_paths_entry *signal_paths_entry_new(const char *signal_name) { + struct signal_paths_entry *e = NULL; - pa_xfree(p); + pa_assert(signal_name); + + e = pa_xnew0(struct signal_paths_entry, 1); + e->signal = pa_xstrdup(signal_name); + e->paths = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + + return e; } -static void free_listening_signals_idxset_cb(void *p, void *userdata) { - pa_idxset *set = p; +static void signal_paths_entry_free(struct signal_paths_entry *e) { + char *path = NULL; + + pa_assert(e); + + pa_xfree(e->signal); - pa_assert(set); + while ((path = pa_idxset_steal_first(e->paths, NULL))) + pa_xfree(path); - pa_idxset_free(set, free_listened_object_name_cb, NULL); + pa_xfree(e); } int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *conn) { - struct connection_entry *conn_entry; + struct connection_entry *conn_entry = NULL; + struct signal_paths_entry *signal_paths_entry = NULL; + char *object_path = NULL; pa_assert(p); pa_assert(conn); @@ -945,8 +964,13 @@ int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection * unregister_all_objects(p, conn); dbus_connection_unref(conn_entry->connection); - pa_idxset_free(conn_entry->all_signals_objects, free_listened_object_name_cb, NULL); - pa_hashmap_free(conn_entry->listening_signals, free_listening_signals_idxset_cb, NULL); + + 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); + pa_xfree(conn_entry); return 0; @@ -970,10 +994,10 @@ void pa_dbus_protocol_add_signal_listener( const char *signal_name, char **objects, unsigned n_objects) { - struct connection_entry *conn_entry; - pa_idxset *object_set; - char *object_path; - unsigned i; + struct connection_entry *conn_entry = NULL; + struct signal_paths_entry *signal_paths_entry = NULL; + char *object_path = NULL; + unsigned i = 0; pa_assert(p); pa_assert(conn); @@ -983,30 +1007,31 @@ 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. */ + * 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); if (signal_name) { conn_entry->listening_for_all_signals = FALSE; - /* Replace the old object list with a new one. */ - if ((object_set = pa_hashmap_remove(conn_entry->listening_signals, signal_name))) - pa_idxset_free(object_set, free_listened_object_name_cb, NULL); - object_set = pa_idxset_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); + /* 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); + signal_paths_entry = signal_paths_entry_new(signal_name); for (i = 0; i < n_objects; ++i) - pa_idxset_put(object_set, pa_xstrdup(objects[i]), NULL); + pa_idxset_put(signal_paths_entry->paths, pa_xstrdup(objects[i]), NULL); - pa_hashmap_put(conn_entry->listening_signals, signal_name, object_set); + pa_hashmap_put(conn_entry->listening_signals, signal_paths_entry->signal, signal_paths_entry); } else { conn_entry->listening_for_all_signals = TRUE; /* We're not interested in individual signals anymore, so let's empty * listening_signals. */ - while ((object_set = pa_hashmap_steal_first(conn_entry->listening_signals))) - pa_idxset_free(object_set, free_listened_object_name_cb, NULL); + while ((signal_paths_entry = pa_hashmap_steal_first(conn_entry->listening_signals))) + signal_paths_entry_free(signal_paths_entry); for (i = 0; i < n_objects; ++i) pa_idxset_put(conn_entry->all_signals_objects, pa_xstrdup(objects[i]), NULL); @@ -1014,8 +1039,8 @@ void pa_dbus_protocol_add_signal_listener( } void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection *conn, const char *signal_name) { - struct connection_entry *conn_entry; - pa_idxset *object_set; + struct connection_entry *conn_entry = NULL; + struct signal_paths_entry *signal_paths_entry = NULL; pa_assert(p); pa_assert(conn); @@ -1023,8 +1048,8 @@ 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 ((object_set = pa_hashmap_get(conn_entry->listening_signals, signal_name))) - pa_idxset_free(object_set, free_listened_object_name_cb, NULL); + if ((signal_paths_entry = pa_hashmap_get(conn_entry->listening_signals, signal_name))) + signal_paths_entry_free(signal_paths_entry); } else { char *object_path; @@ -1034,37 +1059,38 @@ void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection while ((object_path = pa_idxset_steal_first(conn_entry->all_signals_objects, NULL))) pa_xfree(object_path); - while ((object_set = pa_hashmap_steal_first(conn_entry->listening_signals))) - pa_idxset_free(object_set, free_listened_object_name_cb, NULL); + while ((signal_paths_entry = pa_hashmap_steal_first(conn_entry->listening_signals))) + signal_paths_entry_free(signal_paths_entry); } } -void pa_dbus_protocol_send_signal(pa_dbus_protocol *p, DBusMessage *signal_name) { +void pa_dbus_protocol_send_signal(pa_dbus_protocol *p, DBusMessage *signal_msg) { struct connection_entry *conn_entry; + struct signal_paths_entry *signal_paths_entry; void *state = NULL; - pa_idxset *object_set; DBusMessage *signal_copy; char *signal_string; pa_assert(p); - pa_assert(signal_name); - pa_assert(dbus_message_get_type(signal_name) == DBUS_MESSAGE_TYPE_SIGNAL); - pa_assert_se(dbus_message_get_interface(signal_name)); - pa_assert_se(dbus_message_get_member(signal_name)); + pa_assert(signal_msg); + pa_assert(dbus_message_get_type(signal_msg) == DBUS_MESSAGE_TYPE_SIGNAL); + pa_assert(dbus_message_get_path(signal_msg)); + pa_assert(dbus_message_get_interface(signal_msg)); + pa_assert(dbus_message_get_member(signal_msg)); - signal_string = pa_sprintf_malloc("%s.%s", dbus_message_get_interface(signal_name), dbus_message_get_member(signal_name)); + signal_string = pa_sprintf_malloc("%s.%s", dbus_message_get_interface(signal_msg), dbus_message_get_member(signal_msg)); PA_HASHMAP_FOREACH(conn_entry, p->connections, state) { if ((conn_entry->listening_for_all_signals /* Case 1: listening for all signals */ - && (pa_idxset_get_by_data(conn_entry->all_signals_objects, dbus_message_get_path(signal_name), NULL) + && (pa_idxset_get_by_data(conn_entry->all_signals_objects, dbus_message_get_path(signal_msg), NULL) || pa_idxset_isempty(conn_entry->all_signals_objects))) || (!conn_entry->listening_for_all_signals /* Case 2: not listening for all signals */ - && (object_set = pa_hashmap_get(conn_entry->listening_signals, signal_string)) - && (pa_idxset_get_by_data(object_set, dbus_message_get_path(signal_name), NULL) - || pa_idxset_isempty(object_set)))) { + && (signal_paths_entry = pa_hashmap_get(conn_entry->listening_signals, signal_string)) + && (pa_idxset_get_by_data(signal_paths_entry->paths, dbus_message_get_path(signal_msg), NULL) + || pa_idxset_isempty(signal_paths_entry->paths)))) { - pa_assert_se(signal_copy = dbus_message_copy(signal_name)); + pa_assert_se(signal_copy = dbus_message_copy(signal_msg)); pa_assert_se(dbus_connection_send(conn_entry->connection, signal_copy, NULL)); dbus_message_unref(signal_copy); } |