hashmap: Add the ability to free keys

Since the hashmap stores a pointer to the key provided at pa_hashmap_put()
time, it make sense to allow the hashmap to be given ownership of the key and
have it free it at pa_hashmap_remove/free time.

To do this cleanly, we now provide the key and value free functions at hashmap
creation time with a pa_hashmap_new_full. With this, we do away with the free
function that was provided at remove/free time for freeing the value.
This commit is contained in:
Arun Raghavan 2013-09-14 11:50:10 +05:30
parent 317b46b571
commit 6825df8cec
41 changed files with 232 additions and 205 deletions

View file

@ -495,7 +495,7 @@ static pa_hook_result_t card_profile_added_cb(void *hook_data, void *call_data,
return PA_HOOK_OK;
p = pa_dbusiface_card_profile_new(c, core, profile, c->next_profile_index++);
pa_assert_se(pa_hashmap_put(c->profiles, pa_dbusiface_card_profile_get_name(p), p) >= 0);
pa_assert_se(pa_hashmap_put(c->profiles, (char *) pa_dbusiface_card_profile_get_name(p), p) >= 0);
/* Send D-Bus signal */
object_path = pa_dbusiface_card_profile_get_path(p);
@ -523,7 +523,8 @@ pa_dbusiface_card *pa_dbusiface_card_new(pa_dbusiface_core *core, pa_card *card)
c->core = core;
c->card = card;
c->path = pa_sprintf_malloc("%s/%s%u", PA_DBUS_CORE_OBJECT_PATH, OBJECT_NAME, card->index);
c->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
c->profiles = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
(pa_free_cb_t) pa_dbusiface_card_profile_free);
c->next_profile_index = 0;
c->active_profile = card->active_profile;
c->proplist = pa_proplist_copy(card->proplist);
@ -532,7 +533,7 @@ pa_dbusiface_card *pa_dbusiface_card_new(pa_dbusiface_core *core, pa_card *card)
PA_HASHMAP_FOREACH(profile, card->profiles, state) {
pa_dbusiface_card_profile *p = pa_dbusiface_card_profile_new(c, card->core, profile, c->next_profile_index++);
pa_hashmap_put(c->profiles, pa_dbusiface_card_profile_get_name(p), p);
pa_hashmap_put(c->profiles, (char *) pa_dbusiface_card_profile_get_name(p), p);
}
pa_assert_se(pa_dbus_protocol_add_interface(c->dbus_protocol, c->path, &card_interface_info, c) >= 0);
@ -550,7 +551,7 @@ void pa_dbusiface_card_free(pa_dbusiface_card *c) {
pa_hook_slot_free(c->card_profile_added_slot);
pa_hashmap_free(c->profiles, (pa_free_cb_t) pa_dbusiface_card_profile_free);
pa_hashmap_free(c->profiles);
pa_proplist_free(c->proplist);
pa_dbus_protocol_unref(c->dbus_protocol);
pa_subscription_free(c->subscription);

View file

@ -1870,7 +1870,7 @@ static pa_hook_result_t sink_put_cb(void *hook_data, void *call_data, void *slot
object_path = pa_dbusiface_device_get_path(d);
pa_assert_se(pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0);
pa_assert_se(pa_hashmap_put(c->sinks_by_path, object_path, d) >= 0);
pa_assert_se(pa_hashmap_put(c->sinks_by_path, (char *) object_path, d) >= 0);
pa_assert_se(signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
PA_DBUS_CORE_INTERFACE,
@ -1924,7 +1924,7 @@ static pa_hook_result_t source_put_cb(void *hook_data, void *call_data, void *sl
object_path = pa_dbusiface_device_get_path(d);
pa_assert_se(pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(s->index), d) >= 0);
pa_assert_se(pa_hashmap_put(c->sources_by_path, object_path, d) >= 0);
pa_assert_se(pa_hashmap_put(c->sources_by_path, (char *) object_path, d) >= 0);
pa_assert_se((signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
PA_DBUS_CORE_INTERFACE,
@ -2021,16 +2021,20 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
c->core = core;
c->subscription = pa_subscription_new(core, PA_SUBSCRIPTION_MASK_ALL, subscription_cb, c);
c->dbus_protocol = pa_dbus_protocol_get(core);
c->cards = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
c->sinks_by_index = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
c->cards = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_card_free);
c->sinks_by_index = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
(pa_free_cb_t) pa_dbusiface_device_free);
c->sinks_by_path = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
c->sources_by_index = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
c->sources_by_index = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
(pa_free_cb_t) pa_dbusiface_device_free);
c->sources_by_path = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
c->playback_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
c->record_streams = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
c->samples = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
c->modules = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
c->clients = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
c->playback_streams = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
(pa_free_cb_t) pa_dbusiface_stream_free);
c->record_streams = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL,
(pa_free_cb_t) pa_dbusiface_stream_free);
c->samples = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_sample_free);
c->modules = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_module_free);
c->clients = pa_hashmap_new_full(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_client_free);
c->fallback_sink = pa_namereg_get_default_sink(core);
c->fallback_source = pa_namereg_get_default_source(core);
c->sink_put_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_NORMAL, sink_put_cb, c);
@ -2060,13 +2064,13 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
PA_IDXSET_FOREACH(sink, core->sinks, idx) {
device = pa_dbusiface_device_new_sink(c, sink);
pa_hashmap_put(c->sinks_by_index, PA_UINT32_TO_PTR(idx), device);
pa_hashmap_put(c->sinks_by_path, pa_dbusiface_device_get_path(device), device);
pa_hashmap_put(c->sinks_by_path, (char *) pa_dbusiface_device_get_path(device), device);
}
PA_IDXSET_FOREACH(source, core->sources, idx) {
device = pa_dbusiface_device_new_source(c, source);
pa_hashmap_put(c->sources_by_index, PA_UINT32_TO_PTR(idx), device);
pa_hashmap_put(c->sources_by_path, pa_dbusiface_device_get_path(device), device);
pa_hashmap_put(c->sources_by_path, (char *) pa_dbusiface_device_get_path(device), device);
}
PA_IDXSET_FOREACH(sink_input, core->sink_inputs, idx)
@ -2097,16 +2101,16 @@ void pa_dbusiface_core_free(pa_dbusiface_core *c) {
/* Note that the order of freeing is important below.
* Do not change it for the sake of tidiness without checking! */
pa_subscription_free(c->subscription);
pa_hashmap_free(c->cards, (pa_free_cb_t) pa_dbusiface_card_free);
pa_hashmap_free(c->sinks_by_path, NULL);
pa_hashmap_free(c->sinks_by_index, (pa_free_cb_t) pa_dbusiface_device_free);
pa_hashmap_free(c->sources_by_path, NULL);
pa_hashmap_free(c->sources_by_index, (pa_free_cb_t) pa_dbusiface_device_free);
pa_hashmap_free(c->playback_streams, (pa_free_cb_t) pa_dbusiface_stream_free);
pa_hashmap_free(c->record_streams, (pa_free_cb_t) pa_dbusiface_stream_free);
pa_hashmap_free(c->samples, (pa_free_cb_t) pa_dbusiface_sample_free);
pa_hashmap_free(c->modules, (pa_free_cb_t) pa_dbusiface_module_free);
pa_hashmap_free(c->clients, (pa_free_cb_t) pa_dbusiface_client_free);
pa_hashmap_free(c->cards);
pa_hashmap_free(c->sinks_by_path);
pa_hashmap_free(c->sinks_by_index);
pa_hashmap_free(c->sources_by_path);
pa_hashmap_free(c->sources_by_index);
pa_hashmap_free(c->playback_streams);
pa_hashmap_free(c->record_streams);
pa_hashmap_free(c->samples);
pa_hashmap_free(c->modules);
pa_hashmap_free(c->clients);
pa_hook_slot_free(c->sink_put_slot);
pa_hook_slot_free(c->sink_unlink_slot);
pa_hook_slot_free(c->source_put_slot);

View file

@ -1214,7 +1214,7 @@ pa_dbusiface_device *pa_dbusiface_device_new_sink(pa_dbusiface_core *core, pa_si
d->volume = *pa_sink_get_volume(sink, false);
d->mute = pa_sink_get_mute(sink, false);
d->sink_state = pa_sink_get_state(sink);
d->ports = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
d->ports = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, (pa_free_cb_t) pa_dbusiface_device_port_free);
d->next_port_index = 0;
d->active_port = sink->active_port;
d->proplist = pa_proplist_copy(sink->proplist);
@ -1223,7 +1223,7 @@ pa_dbusiface_device *pa_dbusiface_device_new_sink(pa_dbusiface_core *core, pa_si
PA_HASHMAP_FOREACH(port, sink->ports, state) {
pa_dbusiface_device_port *p = pa_dbusiface_device_port_new(d, sink->core, port, d->next_port_index++);
pa_hashmap_put(d->ports, pa_dbusiface_device_port_get_name(p), p);
pa_hashmap_put(d->ports, (char *) pa_dbusiface_device_port_get_name(p), p);
}
pa_assert_se(pa_dbus_protocol_add_interface(d->dbus_protocol, d->path, &device_interface_info, d) >= 0);
@ -1257,7 +1257,7 @@ pa_dbusiface_device *pa_dbusiface_device_new_source(pa_dbusiface_core *core, pa_
PA_HASHMAP_FOREACH(port, source->ports, state) {
pa_dbusiface_device_port *p = pa_dbusiface_device_port_new(d, source->core, port, d->next_port_index++);
pa_hashmap_put(d->ports, pa_dbusiface_device_port_get_name(p), p);
pa_hashmap_put(d->ports, (char *) pa_dbusiface_device_port_get_name(p), p);
}
pa_assert_se(pa_dbus_protocol_add_interface(d->dbus_protocol, d->path, &device_interface_info, d) >= 0);
@ -1279,7 +1279,7 @@ void pa_dbusiface_device_free(pa_dbusiface_device *d) {
pa_assert_se(pa_dbus_protocol_remove_interface(d->dbus_protocol, d->path, source_interface_info.name) >= 0);
pa_source_unref(d->source);
}
pa_hashmap_free(d->ports, (pa_free_cb_t) pa_dbusiface_device_port_free);
pa_hashmap_free(d->ports);
pa_proplist_free(d->proplist);
pa_dbus_protocol_unref(d->dbus_protocol);
pa_subscription_free(d->subscription);