[pulseaudio-discuss] [PATCH] hashmap: Allow freeing of keys in addition to values

Arun Raghavan arun.raghavan at collabora.co.uk
Tue Aug 6 02:02:25 PDT 2013


This is handy for cases where we want to have the key freed at entry
removal or hashmap free'ing time. For example, this is useful when
creating a hashmap based on non-static strings.
---
 src/modules/alsa/alsa-mixer.c                      | 28 ++++++-------
 src/modules/alsa/module-alsa-card.c                |  2 +-
 src/modules/bluetooth/bluetooth-util.c             | 14 +++----
 src/modules/bluetooth/module-bluetooth-discover.c  |  6 +--
 src/modules/bluetooth/module-bluetooth-proximity.c |  6 +--
 src/modules/dbus/iface-card.c                      |  6 +--
 src/modules/dbus/iface-core.c                      | 48 +++++++++++-----------
 src/modules/dbus/iface-device.c                    |  6 +--
 src/modules/gconf/module-gconf.c                   |  4 +-
 src/modules/macosx/module-bonjour-publish.c        |  4 +-
 src/modules/module-augment-properties.c            |  4 +-
 src/modules/module-card-restore.c                  |  2 +-
 src/modules/module-console-kit.c                   |  4 +-
 src/modules/module-device-manager.c                | 16 ++++----
 src/modules/module-filter-apply.c                  | 10 ++---
 src/modules/module-role-cork.c                     |  6 +--
 src/modules/module-stream-restore.c                |  8 ++--
 src/modules/module-suspend-on-idle.c               |  4 +-
 src/modules/module-systemd-login.c                 |  8 ++--
 src/modules/module-udev-detect.c                   |  4 +-
 src/modules/module-zeroconf-discover.c             |  6 +--
 src/modules/module-zeroconf-publish.c              |  6 +--
 src/modules/raop/module-raop-discover.c            |  6 +--
 src/modules/rtp/headerlist.c                       |  4 +-
 src/modules/rtp/module-rtp-recv.c                  |  8 ++--
 src/pulse/context.c                                |  4 +-
 src/pulse/proplist.c                               |  6 +--
 src/pulse/stream.c                                 |  3 +-
 src/pulsecore/card.c                               |  8 ++--
 src/pulsecore/core.c                               |  4 +-
 src/pulsecore/database-simple.c                    | 10 ++---
 src/pulsecore/device-port.c                        |  2 +-
 src/pulsecore/hashmap.c                            | 29 +++++++------
 src/pulsecore/hashmap.h                            | 14 +++----
 src/pulsecore/memblock.c                           | 10 ++---
 src/pulsecore/modargs.c                            |  4 +-
 src/pulsecore/mutex-win32.c                        |  4 +-
 src/pulsecore/namereg.c                            |  2 +-
 src/pulsecore/protocol-dbus.c                      | 34 +++++++--------
 src/pulsecore/protocol-native.c                    |  4 +-
 src/pulsecore/shared.c                             |  2 +-
 src/pulsecore/sink-input.c                         | 12 +++---
 src/pulsecore/sink.c                               | 10 ++---
 src/pulsecore/source.c                             | 10 ++---
 44 files changed, 198 insertions(+), 194 deletions(-)

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 545ae9f..fe5b7b1 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -530,7 +530,7 @@ void pa_alsa_path_set_free(pa_alsa_path_set *ps) {
     pa_assert(ps);
 
     if (ps->paths)
-        pa_hashmap_free(ps->paths, NULL);
+        pa_hashmap_free(ps->paths, NULL, NULL);
 
     pa_xfree(ps);
 }
@@ -3237,7 +3237,7 @@ static void path_set_condense(pa_alsa_path_set *ps, snd_mixer_t *m) {
 
             if (is_subset) {
                 pa_log_debug("Removing path '%s' as it is a subset of '%s'.", p->name, p2->name);
-                pa_hashmap_remove(ps->paths, p);
+                pa_hashmap_remove(ps->paths, p, NULL);
                 break;
             }
         }
@@ -3337,19 +3337,19 @@ void pa_alsa_profile_set_free(pa_alsa_profile_set *ps) {
     pa_assert(ps);
 
     if (ps->input_paths)
-        pa_hashmap_free(ps->input_paths, (pa_free_cb_t) pa_alsa_path_free);
+        pa_hashmap_free(ps->input_paths, NULL, (pa_free_cb_t) pa_alsa_path_free);
 
     if (ps->output_paths)
-        pa_hashmap_free(ps->output_paths, (pa_free_cb_t) pa_alsa_path_free);
+        pa_hashmap_free(ps->output_paths, NULL, (pa_free_cb_t) pa_alsa_path_free);
 
     if (ps->profiles)
-        pa_hashmap_free(ps->profiles, (pa_free_cb_t) profile_free);
+        pa_hashmap_free(ps->profiles, NULL, (pa_free_cb_t) profile_free);
 
     if (ps->mappings)
-        pa_hashmap_free(ps->mappings, (pa_free_cb_t) mapping_free);
+        pa_hashmap_free(ps->mappings, NULL, (pa_free_cb_t) mapping_free);
 
     if (ps->decibel_fixes)
-        pa_hashmap_free(ps->decibel_fixes, (pa_free_cb_t) decibel_fix_free);
+        pa_hashmap_free(ps->decibel_fixes, NULL, (pa_free_cb_t) decibel_fix_free);
 
     pa_xfree(ps);
 }
@@ -3776,13 +3776,13 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
     mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL, &hctl_handle);
     if (!mixer_handle || !hctl_handle) {
          /* Cannot open mixer, remove all entries */
-        pa_hashmap_remove_all(ps->paths, NULL);
+        pa_hashmap_remove_all(ps->paths, NULL, NULL);
         return;
     }
 
     PA_HASHMAP_FOREACH(p, ps->paths, state) {
         if (pa_alsa_path_probe(p, mixer_handle, hctl_handle, m->profile_set->ignore_dB) < 0) {
-            pa_hashmap_remove(ps->paths, p);
+            pa_hashmap_remove(ps->paths, p, NULL);
         }
     }
 
@@ -4290,7 +4290,7 @@ static void paths_drop_unsupported(pa_hashmap* h) {
     p = pa_hashmap_iterate(h, &state, &key);
     while (p) {
         if (p->supported <= 0) {
-            pa_hashmap_remove(h, key);
+            pa_hashmap_remove(h, key, NULL);
             pa_alsa_path_free(p);
         }
         p = pa_hashmap_iterate(h, &state, &key);
@@ -4420,8 +4420,8 @@ void pa_alsa_profile_set_probe(
 
     paths_drop_unsupported(ps->input_paths);
     paths_drop_unsupported(ps->output_paths);
-    pa_hashmap_free(broken_inputs, NULL);
-    pa_hashmap_free(broken_outputs, NULL);
+    pa_hashmap_free(broken_inputs, NULL, NULL);
+    pa_hashmap_free(broken_outputs, NULL, NULL);
 
     ps->probed = true;
 }
@@ -4460,14 +4460,14 @@ void pa_alsa_profile_set_drop_unsupported(pa_alsa_profile_set *ps) {
 
     PA_HASHMAP_FOREACH(p, ps->profiles, state) {
         if (!p->supported) {
-            pa_hashmap_remove(ps->profiles, p->name);
+            pa_hashmap_remove(ps->profiles, p->name, NULL);
             profile_free(p);
         }
     }
 
     PA_HASHMAP_FOREACH(m, ps->mappings, state) {
         if (m->supported <= 0) {
-            pa_hashmap_remove(ps->mappings, m->name);
+            pa_hashmap_remove(ps->mappings, m->name, NULL);
             mapping_free(m);
         }
     }
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index d0294e8..d242fc8 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -871,7 +871,7 @@ void pa__done(pa_module*m) {
     if (u->mixer_handle)
         snd_mixer_close(u->mixer_handle);
     if (u->jacks)
-        pa_hashmap_free(u->jacks, NULL);
+        pa_hashmap_free(u->jacks, NULL, NULL);
 
     if (u->card && u->card->sinks)
         pa_idxset_remove_all(u->card->sinks, (pa_free_cb_t) pa_alsa_sink_free);
diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index dd280cb..4b0f67e 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -262,7 +262,7 @@ static void device_free(pa_bluetooth_device *d) {
             continue;
 
         d->transports[i] = NULL;
-        pa_hashmap_remove(d->discovery->transports, t->path);
+        pa_hashmap_remove(d->discovery->transports, t->path, NULL);
         t->state = PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED;
         pa_hook_fire(&d->discovery->hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t);
         transport_free(t);
@@ -675,7 +675,7 @@ static void remove_all_devices(pa_bluetooth_discovery *y) {
 
     pa_assert(y);
 
-    while ((d = pa_hashmap_steal_first(y->devices))) {
+    while ((d = pa_hashmap_steal_first(y->devices, NULL))) {
         run_callback(d, true);
         device_free(d);
     }
@@ -1172,7 +1172,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
 
         pa_log_debug("Device %s removed", path);
 
-        if ((d = pa_hashmap_remove(y->devices, path))) {
+        if ((d = pa_hashmap_remove(y->devices, path, NULL))) {
             run_callback(d, true);
             device_free(d);
         }
@@ -1327,7 +1327,7 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
             if (pa_streq(interface, "org.bluez.Device1")) {
                 pa_bluetooth_device *d;
 
-                if (!(d = pa_hashmap_remove(y->devices, path)))
+                if (!(d = pa_hashmap_remove(y->devices, path, NULL)))
                     pa_log_warn("Unknown device removed %s", path);
                 else {
                     pa_log_debug("Device %s removed", path);
@@ -1772,7 +1772,7 @@ static DBusMessage *endpoint_clear_configuration(DBusConnection *c, DBusMessage
 
         pa_log_debug("Clearing transport %s profile %d", t->path, t->profile);
         t->device->transports[t->profile] = NULL;
-        pa_hashmap_remove(y->transports, t->path);
+        pa_hashmap_remove(y->transports, t->path, NULL);
         t->state = PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED;
         pa_hook_fire(&y->hooks[PA_BLUETOOTH_HOOK_TRANSPORT_STATE_CHANGED], t);
 
@@ -2109,12 +2109,12 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
 
     if (y->devices) {
         remove_all_devices(y);
-        pa_hashmap_free(y->devices, NULL);
+        pa_hashmap_free(y->devices, NULL, NULL);
     }
 
     if (y->transports) {
         pa_assert(pa_hashmap_isempty(y->transports));
-        pa_hashmap_free(y->transports, NULL);
+        pa_hashmap_free(y->transports, NULL, NULL);
     }
 
     if (y->connection) {
diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c
index cbd56cc..496cc64 100644
--- a/src/modules/bluetooth/module-bluetooth-discover.c
+++ b/src/modules/bluetooth/module-bluetooth-discover.c
@@ -115,7 +115,7 @@ static pa_hook_result_t load_module_for_device(pa_bluetooth_discovery *y, const
             /* Hmm, disconnection? Then the module unloads itself */
 
             pa_log_debug("Unregistering module for %s", d->path);
-            pa_hashmap_remove(u->hashmap, mi->path);
+            pa_hashmap_remove(u->hashmap, mi->path, NULL);
             pa_xfree(mi->path);
             pa_xfree(mi);
         }
@@ -179,12 +179,12 @@ void pa__done(pa_module* m) {
     if (u->hashmap) {
         struct module_info *mi;
 
-        while ((mi = pa_hashmap_steal_first(u->hashmap))) {
+        while ((mi = pa_hashmap_steal_first(u->hashmap, NULL))) {
             pa_xfree(mi->path);
             pa_xfree(mi);
         }
 
-        pa_hashmap_free(u->hashmap, NULL);
+        pa_hashmap_free(u->hashmap, NULL, NULL);
     }
 
     if (u->modargs)
diff --git a/src/modules/bluetooth/module-bluetooth-proximity.c b/src/modules/bluetooth/module-bluetooth-proximity.c
index c4e6ca6..24b4f55 100644
--- a/src/modules/bluetooth/module-bluetooth-proximity.c
+++ b/src/modules/bluetooth/module-bluetooth-proximity.c
@@ -167,7 +167,7 @@ static void io_event_cb(
     if ((r = read(fd, &x, 1)) <= 0) {
         pa_log_warn("Child watching '%s' died abnormally: %s", b->address, r == 0 ? "EOF" : pa_cstrerror(errno));
 
-        pa_assert_se(pa_hashmap_remove(b->userdata->bondings, b->address) == b);
+        pa_assert_se(pa_hashmap_remove(b->userdata->bondings, b->address, NULL) == b);
         bonding_free(b);
         return;
     }
@@ -280,7 +280,7 @@ static void bonding_remove(struct userdata *u, const char *a) {
     struct bonding *b;
     pa_assert(u);
 
-    pa_return_if_fail((b = pa_hashmap_remove(u->bondings, a)));
+    pa_return_if_fail((b = pa_hashmap_remove(u->bondings, a, NULL)));
 
     pa_log_info("No longer watching device '%s'", b->address);
     bonding_free(b);
@@ -466,7 +466,7 @@ void pa__done(pa_module*m) {
         return;
 
     if (u->bondings)
-        pa_hashmap_free(u->bondings, (pa_free_cb_t) bonding_free);
+        pa_hashmap_free(u->bondings, NULL, (pa_free_cb_t) bonding_free);
 
     if (u->dbus_connection) {
         update_matches(u, false);
diff --git a/src/modules/dbus/iface-card.c b/src/modules/dbus/iface-card.c
index 19dd4ed..49a0abf 100644
--- a/src/modules/dbus/iface-card.c
+++ b/src/modules/dbus/iface-card.c
@@ -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);
@@ -532,7 +532,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 +550,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, NULL, (pa_free_cb_t) pa_dbusiface_card_profile_free);
     pa_proplist_free(c->proplist);
     pa_dbus_protocol_unref(c->dbus_protocol);
     pa_subscription_free(c->subscription);
diff --git a/src/modules/dbus/iface-core.c b/src/modules/dbus/iface-core.c
index edc22ab..c1c968b 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -1665,7 +1665,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
                 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
 
             } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-                if (!(card_iface = pa_hashmap_remove(c->cards, PA_UINT32_TO_PTR(idx))))
+                if (!(card_iface = pa_hashmap_remove(c->cards, PA_UINT32_TO_PTR(idx), NULL)))
                     return;
 
                 object_path = pa_dbusiface_card_get_path(card_iface);
@@ -1699,7 +1699,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
                 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
 
             } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-                if (!(stream_iface = pa_hashmap_remove(c->playback_streams, PA_UINT32_TO_PTR(idx))))
+                if (!(stream_iface = pa_hashmap_remove(c->playback_streams, PA_UINT32_TO_PTR(idx), NULL)))
                     return;
 
                 object_path = pa_dbusiface_stream_get_path(stream_iface);
@@ -1733,7 +1733,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
                 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
 
             } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-                if (!(stream_iface = pa_hashmap_remove(c->record_streams, PA_UINT32_TO_PTR(idx))))
+                if (!(stream_iface = pa_hashmap_remove(c->record_streams, PA_UINT32_TO_PTR(idx), NULL)))
                     return;
 
                 object_path = pa_dbusiface_stream_get_path(stream_iface);
@@ -1767,7 +1767,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
                 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
 
             } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-                if (!(sample_iface = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(idx))))
+                if (!(sample_iface = pa_hashmap_remove(c->samples, PA_UINT32_TO_PTR(idx), NULL)))
                     return;
 
                 object_path = pa_dbusiface_sample_get_path(sample_iface);
@@ -1801,7 +1801,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
                 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
 
             } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-                if (!(module_iface = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(idx))))
+                if (!(module_iface = pa_hashmap_remove(c->modules, PA_UINT32_TO_PTR(idx), NULL)))
                     return;
 
                 object_path = pa_dbusiface_module_get_path(module_iface);
@@ -1835,7 +1835,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t t, uint3
                 pa_assert_se(dbus_message_append_args(signal_msg, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID));
 
             } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-                if (!(client_iface = pa_hashmap_remove(c->clients, PA_UINT32_TO_PTR(idx))))
+                if (!(client_iface = pa_hashmap_remove(c->clients, PA_UINT32_TO_PTR(idx), NULL)))
                     return;
 
                 object_path = pa_dbusiface_client_get_path(client_iface);
@@ -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,
@@ -1893,9 +1893,9 @@ static pa_hook_result_t sink_unlink_cb(void *hook_data, void *call_data, void *s
     pa_assert(c);
     pa_assert(s);
 
-    pa_assert_se(d = pa_hashmap_remove(c->sinks_by_index, PA_UINT32_TO_PTR(s->index)));
+    pa_assert_se(d = pa_hashmap_remove(c->sinks_by_index, PA_UINT32_TO_PTR(s->index), NULL));
     object_path = pa_dbusiface_device_get_path(d);
-    pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path));
+    pa_assert_se(pa_hashmap_remove(c->sinks_by_path, object_path, NULL));
 
     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,
@@ -1947,9 +1947,9 @@ static pa_hook_result_t source_unlink_cb(void *hook_data, void *call_data, void
     pa_assert(c);
     pa_assert(s);
 
-    pa_assert_se(d = pa_hashmap_remove(c->sources_by_index, PA_UINT32_TO_PTR(s->index)));
+    pa_assert_se(d = pa_hashmap_remove(c->sources_by_index, PA_UINT32_TO_PTR(s->index), NULL));
     object_path = pa_dbusiface_device_get_path(d);
-    pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path));
+    pa_assert_se(pa_hashmap_remove(c->sources_by_path, object_path, NULL));
 
     pa_assert_se(signal_msg = dbus_message_new_signal(PA_DBUS_CORE_OBJECT_PATH,
                                                       PA_DBUS_CORE_INTERFACE,
@@ -2060,13 +2060,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 +2097,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, NULL, (pa_free_cb_t) pa_dbusiface_card_free);
+    pa_hashmap_free(c->sinks_by_path, NULL, NULL);
+    pa_hashmap_free(c->sinks_by_index, NULL, (pa_free_cb_t) pa_dbusiface_device_free);
+    pa_hashmap_free(c->sources_by_path, NULL, NULL);
+    pa_hashmap_free(c->sources_by_index, NULL, (pa_free_cb_t) pa_dbusiface_device_free);
+    pa_hashmap_free(c->playback_streams, NULL, (pa_free_cb_t) pa_dbusiface_stream_free);
+    pa_hashmap_free(c->record_streams, NULL, (pa_free_cb_t) pa_dbusiface_stream_free);
+    pa_hashmap_free(c->samples, NULL, (pa_free_cb_t) pa_dbusiface_sample_free);
+    pa_hashmap_free(c->modules, NULL, (pa_free_cb_t) pa_dbusiface_module_free);
+    pa_hashmap_free(c->clients, NULL, (pa_free_cb_t) pa_dbusiface_client_free);
     pa_hook_slot_free(c->sink_put_slot);
     pa_hook_slot_free(c->sink_unlink_slot);
     pa_hook_slot_free(c->source_put_slot);
diff --git a/src/modules/dbus/iface-device.c b/src/modules/dbus/iface-device.c
index 4af0333..f99512e 100644
--- a/src/modules/dbus/iface-device.c
+++ b/src/modules/dbus/iface-device.c
@@ -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, NULL, (pa_free_cb_t) pa_dbusiface_device_port_free);
     pa_proplist_free(d->proplist);
     pa_dbus_protocol_unref(d->dbus_protocol);
     pa_subscription_free(d->subscription);
diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c
index 448fde5..c43d549 100644
--- a/src/modules/gconf/module-gconf.c
+++ b/src/modules/gconf/module-gconf.c
@@ -290,7 +290,7 @@ static int handle_event(struct userdata *u) {
                     goto fail;
 
                 if ((m = pa_hashmap_get(u->module_infos, name))) {
-                    pa_hashmap_remove(u->module_infos, name);
+                    pa_hashmap_remove(u->module_infos, name, NULL);
                     module_info_free(m);
                 }
 
@@ -401,7 +401,7 @@ void pa__done(pa_module*m) {
         pa_close(u->fd);
 
     if (u->module_infos)
-        pa_hashmap_free(u->module_infos, (pa_free_cb_t) module_info_free);
+        pa_hashmap_free(u->module_infos, NULL, (pa_free_cb_t) module_info_free);
 
     pa_xfree(u);
 }
diff --git a/src/modules/macosx/module-bonjour-publish.c b/src/modules/macosx/module-bonjour-publish.c
index 26081ec..a172c34 100644
--- a/src/modules/macosx/module-bonjour-publish.c
+++ b/src/modules/macosx/module-bonjour-publish.c
@@ -321,7 +321,7 @@ static struct service *get_service(struct userdata *u, pa_object *device) {
 static void service_free(struct service *s) {
     pa_assert(s);
 
-    pa_hashmap_remove(s->userdata->services, s->device);
+    pa_hashmap_remove(s->userdata->services, s->device, NULL);
 
     if (s->service)
         DNSServiceRefDeallocate(s->service);
@@ -490,7 +490,7 @@ void pa__done(pa_module*m) {
     unpublish_all_services(u);
 
     if (u->services)
-        pa_hashmap_free(u->services, NULL);
+        pa_hashmap_free(u->services, NULL, NULL);
 
     if (u->sink_new_slot)
         pa_hook_slot_free(u->sink_new_slot);
diff --git a/src/modules/module-augment-properties.c b/src/modules/module-augment-properties.c
index fcc3462..1c9f7a4 100644
--- a/src/modules/module-augment-properties.c
+++ b/src/modules/module-augment-properties.c
@@ -246,7 +246,7 @@ static void make_room(pa_hashmap *cache) {
     while (pa_hashmap_size(cache) >= MAX_CACHE_SIZE) {
         struct rule *r;
 
-        pa_assert_se(r = pa_hashmap_steal_first(cache));
+        pa_assert_se(r = pa_hashmap_steal_first(cache, NULL));
         rule_free(r);
     }
 }
@@ -348,7 +348,7 @@ void pa__done(pa_module *m) {
         pa_hook_slot_free(u->client_proplist_changed_slot);
 
     if (u->cache)
-        pa_hashmap_free(u->cache, (pa_free_cb_t) rule_free);
+        pa_hashmap_free(u->cache, NULL, (pa_free_cb_t) rule_free);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c
index 928f153..429a462 100644
--- a/src/modules/module-card-restore.c
+++ b/src/modules/module-card-restore.c
@@ -137,7 +137,7 @@ static void entry_free(struct entry* e) {
     pa_assert(e);
 
     pa_xfree(e->profile);
-    pa_hashmap_free(e->ports, (pa_free_cb_t) port_info_free);
+    pa_hashmap_free(e->ports, NULL, (pa_free_cb_t) port_info_free);
 
     pa_xfree(e);
 }
diff --git a/src/modules/module-console-kit.c b/src/modules/module-console-kit.c
index 007d23b..c00d5c3 100644
--- a/src/modules/module-console-kit.c
+++ b/src/modules/module-console-kit.c
@@ -146,7 +146,7 @@ static void free_session(struct session *session) {
 static void remove_session(struct userdata *u, const char *id) {
     struct session *session;
 
-    if (!(session = pa_hashmap_remove(u->sessions, id)))
+    if (!(session = pa_hashmap_remove(u->sessions, id, NULL)))
         return;
 
     free_session(session);
@@ -346,7 +346,7 @@ void pa__done(pa_module *m) {
         return;
 
     if (u->sessions)
-        pa_hashmap_free(u->sessions, (pa_free_cb_t) free_session);
+        pa_hashmap_free(u->sessions, NULL, (pa_free_cb_t) free_session);
 
     if (u->connection) {
         pa_dbus_remove_matches(
diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c
index 6ae9cee..b818f9b 100644
--- a/src/modules/module-device-manager.c
+++ b/src/modules/module-device-manager.c
@@ -1306,24 +1306,24 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
         for (i = 0; i < n_devices; ++i) {
             const char *s;
             if (pa_tagstruct_gets(t, &s) < 0) {
-                while ((device = pa_hashmap_steal_first(h))) {
+                while ((device = pa_hashmap_steal_first(h, NULL))) {
                     pa_xfree(device->device);
                     pa_xfree(device);
                 }
 
-                pa_hashmap_free(h, NULL);
+                pa_hashmap_free(h, NULL, NULL);
                 pa_log_error("Protocol error on reorder");
                 goto fail;
             }
 
             /* Ensure this is a valid entry */
             if (!(e = entry_read(u, s))) {
-                while ((device = pa_hashmap_steal_first(h))) {
+                while ((device = pa_hashmap_steal_first(h, NULL))) {
                     pa_xfree(device->device);
                     pa_xfree(device);
                 }
 
-                pa_hashmap_free(h, NULL);
+                pa_hashmap_free(h, NULL, NULL);
                 pa_log_error("Client specified an unknown device in it's reorder list.");
                 goto fail;
             }
@@ -1333,12 +1333,12 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                 first = false;
                 sink_mode = (0 == strncmp("sink:", s, 5));
             } else if ((sink_mode && 0 != strncmp("sink:", s, 5)) || (!sink_mode && 0 != strncmp("source:", s, 7))) {
-                while ((device = pa_hashmap_steal_first(h))) {
+                while ((device = pa_hashmap_steal_first(h, NULL))) {
                     pa_xfree(device->device);
                     pa_xfree(device);
                 }
 
-                pa_hashmap_free(h, NULL);
+                pa_hashmap_free(h, NULL, NULL);
                 pa_log_error("Attempted to reorder mixed devices (sinks and sources)");
                 goto fail;
             }
@@ -1408,10 +1408,10 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
         n_devices = pa_hashmap_size(h);
         devices = pa_xnew(struct device_t *,  n_devices);
         idx = 0;
-        while ((device = pa_hashmap_steal_first(h))) {
+        while ((device = pa_hashmap_steal_first(h, NULL))) {
             devices[idx++] = device;
         }
-        pa_hashmap_free(h, NULL);
+        pa_hashmap_free(h, NULL, NULL);
 
         /* Simple bubble sort */
         for (i = 0; i < n_devices; ++i) {
diff --git a/src/modules/module-filter-apply.c b/src/modules/module-filter-apply.c
index 05d4284..4e58890 100644
--- a/src/modules/module-filter-apply.c
+++ b/src/modules/module-filter-apply.c
@@ -262,7 +262,7 @@ static void housekeeping_time_callback(pa_mainloop_api*a, pa_time_event* e, cons
 
             pa_log_debug("Detected filter %s as no longer used. Unloading.", filter->name);
             idx = filter->module_index;
-            pa_hashmap_remove(u->filters, filter);
+            pa_hashmap_remove(u->filters, filter, NULL);
             filter_free(filter);
             pa_module_unload_request_by_index(u->core, idx, true);
         }
@@ -577,7 +577,7 @@ static pa_hook_result_t sink_unlink_cb(pa_core *core, pa_sink *sink, struct user
             }
 
             idx = filter->module_index;
-            pa_hashmap_remove(u->filters, filter);
+            pa_hashmap_remove(u->filters, filter, NULL);
             filter_free(filter);
 
             if (can_unload_module(u, idx))
@@ -649,7 +649,7 @@ static pa_hook_result_t source_unlink_cb(pa_core *core, pa_source *source, struc
             }
 
             idx = filter->module_index;
-            pa_hashmap_remove(u->filters, filter);
+            pa_hashmap_remove(u->filters, filter, NULL);
             filter_free(filter);
 
             if (can_unload_module(u, idx))
@@ -742,12 +742,12 @@ void pa__done(pa_module *m) {
     if (u->filters) {
         struct filter *f;
 
-        while ((f = pa_hashmap_steal_first(u->filters))) {
+        while ((f = pa_hashmap_steal_first(u->filters, NULL))) {
             pa_module_unload_request_by_index(u->core, f->module_index, true);
             filter_free(f);
         }
 
-        pa_hashmap_free(u->filters, NULL);
+        pa_hashmap_free(u->filters, NULL, NULL);
     }
 
     pa_xfree(u);
diff --git a/src/modules/module-role-cork.c b/src/modules/module-role-cork.c
index 9906d2e..74a9243 100644
--- a/src/modules/module-role-cork.c
+++ b/src/modules/module-role-cork.c
@@ -129,7 +129,7 @@ static inline void apply_cork_to_sink(struct userdata *u, pa_sink *s, pa_sink_in
             pa_sink_input_set_mute(j, true, false);
             pa_sink_input_send_event(j, PA_STREAM_EVENT_REQUEST_CORK, NULL);
         } else if (!cork) {
-            pa_hashmap_remove(u->cork_state, j);
+            pa_hashmap_remove(u->cork_state, j, NULL);
 
             if (corked_here && (corked || muted)) {
                 pa_log_debug("Found a '%s' stream that should be uncorked/unmuted.", cork_role);
@@ -161,7 +161,7 @@ static pa_hook_result_t process(struct userdata *u, pa_sink_input *i, bool creat
     pa_sink_input_assert_ref(i);
 
     if (!create)
-        pa_hashmap_remove(u->cork_state, i);
+        pa_hashmap_remove(u->cork_state, i, NULL);
 
     if (!(role = pa_proplist_gets(i->proplist, PA_PROP_MEDIA_ROLE)))
         return PA_HOOK_OK;
@@ -304,7 +304,7 @@ void pa__done(pa_module *m) {
         pa_hook_slot_free(u->sink_input_move_finish_slot);
 
     if (u->cork_state)
-        pa_hashmap_free(u->cork_state, NULL);
+        pa_hashmap_free(u->cork_state, NULL, NULL);
 
     pa_xfree(u);
 
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 735dcde..b2ce102 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -949,7 +949,7 @@ static void handle_entry_remove(DBusConnection *conn, DBusMessage *msg, void *us
     send_entry_removed_signal(de);
     trigger_save(de->userdata);
 
-    pa_assert_se(pa_hashmap_remove(de->userdata->dbus_entries, de->entry_name));
+    pa_assert_se(pa_hashmap_remove(de->userdata->dbus_entries, de->entry_name, NULL));
     dbus_entry_free(de);
 
     pa_dbus_send_empty_reply(conn, msg);
@@ -2099,7 +2099,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 
                 PA_HASHMAP_FOREACH(de, u->dbus_entries, state) {
                     send_entry_removed_signal(de);
-                    dbus_entry_free(pa_hashmap_remove(u->dbus_entries, de->entry_name));
+                    dbus_entry_free(pa_hashmap_remove(u->dbus_entries, de->entry_name, NULL));
                 }
 #endif
                 pa_database_clear(u->database);
@@ -2211,7 +2211,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
 #ifdef HAVE_DBUS
                 if ((de = pa_hashmap_get(u->dbus_entries, name))) {
                     send_entry_removed_signal(de);
-                    dbus_entry_free(pa_hashmap_remove(u->dbus_entries, name));
+                    dbus_entry_free(pa_hashmap_remove(u->dbus_entries, name, NULL));
                 }
 #endif
 
@@ -2507,7 +2507,7 @@ void pa__done(pa_module*m) {
         pa_assert_se(pa_dbus_protocol_unregister_extension(u->dbus_protocol, INTERFACE_STREAM_RESTORE) >= 0);
         pa_assert_se(pa_dbus_protocol_remove_interface(u->dbus_protocol, OBJECT_PATH, stream_restore_interface_info.name) >= 0);
 
-        pa_hashmap_free(u->dbus_entries, (pa_free_cb_t) dbus_entry_free);
+        pa_hashmap_free(u->dbus_entries, NULL, (pa_free_cb_t) dbus_entry_free);
 
         pa_dbus_protocol_unref(u->dbus_protocol);
     }
diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c
index 6d49acb..1ef77f8 100644
--- a/src/modules/module-suspend-on-idle.c
+++ b/src/modules/module-suspend-on-idle.c
@@ -376,7 +376,7 @@ static pa_hook_result_t device_unlink_hook_cb(pa_core *c, pa_object *o, struct u
     pa_object_assert_ref(o);
     pa_assert(u);
 
-    if ((d = pa_hashmap_remove(u->device_infos, o)))
+    if ((d = pa_hashmap_remove(u->device_infos, o, NULL)))
         device_info_free(d);
 
     return PA_HOOK_OK;
@@ -518,7 +518,7 @@ void pa__done(pa_module*m) {
     if (u->source_output_state_changed_slot)
         pa_hook_slot_free(u->source_output_state_changed_slot);
 
-    pa_hashmap_free(u->device_infos, (pa_free_cb_t) device_info_free);
+    pa_hashmap_free(u->device_infos, NULL, (pa_free_cb_t) device_info_free);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-systemd-login.c b/src/modules/module-systemd-login.c
index 18f8cc5..2c60a3a 100644
--- a/src/modules/module-systemd-login.c
+++ b/src/modules/module-systemd-login.c
@@ -128,7 +128,7 @@ static int get_session_list(struct userdata *u) {
          * this here. */
 
         for (s = sessions; *s; s++) {
-            o = pa_hashmap_remove(u->previous_sessions, *s);
+            o = pa_hashmap_remove(u->previous_sessions, *s, NULL);
             if (o)
                 pa_hashmap_put(u->sessions, o->id, o);
             else
@@ -140,7 +140,7 @@ static int get_session_list(struct userdata *u) {
         free(sessions);
     }
 
-    pa_hashmap_remove_all(u->previous_sessions, (pa_free_cb_t) free_session);
+    pa_hashmap_remove_all(u->previous_sessions, NULL, (pa_free_cb_t) free_session);
 
     return 0;
 }
@@ -219,8 +219,8 @@ void pa__done(pa_module *m) {
         return;
 
     if (u->sessions) {
-        pa_hashmap_free(u->sessions, (pa_free_cb_t) free_session);
-        pa_hashmap_free(u->previous_sessions, (pa_free_cb_t) free_session);
+        pa_hashmap_free(u->sessions, NULL, (pa_free_cb_t)free_session);
+        pa_hashmap_free(u->previous_sessions, NULL, (pa_free_cb_t)free_session);
     }
 
     if (u->io)
diff --git a/src/modules/module-udev-detect.c b/src/modules/module-udev-detect.c
index fcedfcd..0dd5793 100644
--- a/src/modules/module-udev-detect.c
+++ b/src/modules/module-udev-detect.c
@@ -436,7 +436,7 @@ static void remove_card(struct userdata *u, struct udev_device *dev) {
     pa_assert(u);
     pa_assert(dev);
 
-    if (!(d = pa_hashmap_remove(u->devices, udev_device_get_devpath(dev))))
+    if (!(d = pa_hashmap_remove(u->devices, udev_device_get_devpath(dev), NULL)))
         return;
 
     pa_log_info("Card %s removed.", d->path);
@@ -841,7 +841,7 @@ void pa__done(pa_module *m) {
         pa_close(u->inotify_fd);
 
     if (u->devices)
-        pa_hashmap_free(u->devices, (pa_free_cb_t) device_free);
+        pa_hashmap_free(u->devices, NULL, (pa_free_cb_t) device_free);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-zeroconf-discover.c b/src/modules/module-zeroconf-discover.c
index 4ec3747..0652e9a 100644
--- a/src/modules/module-zeroconf-discover.c
+++ b/src/modules/module-zeroconf-discover.c
@@ -282,7 +282,7 @@ static void browser_cb(
 
         if ((t2 = pa_hashmap_get(u->tunnels, t))) {
             pa_module_unload_request_by_index(u->core, t2->module_index, true);
-            pa_hashmap_remove(u->tunnels, t2);
+            pa_hashmap_remove(u->tunnels, t2, NULL);
             tunnel_free(t2);
         }
     }
@@ -421,12 +421,12 @@ void pa__done(pa_module*m) {
     if (u->tunnels) {
         struct tunnel *t;
 
-        while ((t = pa_hashmap_steal_first(u->tunnels))) {
+        while ((t = pa_hashmap_steal_first(u->tunnels, NULL))) {
             pa_module_unload_request_by_index(u->core, t->module_index, true);
             tunnel_free(t);
         }
 
-        pa_hashmap_free(u->tunnels, NULL);
+        pa_hashmap_free(u->tunnels, NULL, NULL);
     }
 
     pa_xfree(u);
diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c
index 3350008..fe1f8f8 100644
--- a/src/modules/module-zeroconf-publish.c
+++ b/src/modules/module-zeroconf-publish.c
@@ -374,7 +374,7 @@ finish:
 
     /* Remove this service */
     if (r < 0) {
-        pa_hashmap_remove(s->userdata->services, s->key);
+        pa_hashmap_remove(s->userdata->services, s->key, NULL);
         service_free(s);
     }
 
@@ -474,7 +474,7 @@ static pa_hook_result_t device_unlink_cb(pa_core *c, pa_object *o, struct userda
 
     pa_threaded_mainloop_lock(u->mainloop);
 
-    if ((s = pa_hashmap_remove(u->services, o)))
+    if ((s = pa_hashmap_remove(u->services, o, NULL)))
         service_free(s);
 
     pa_threaded_mainloop_unlock(u->mainloop);
@@ -786,7 +786,7 @@ fail:
 static void client_free(pa_mainloop_api *api PA_GCC_UNUSED, void *userdata) {
     struct userdata *u = (struct userdata *) userdata;
 
-    pa_hashmap_free(u->services, (pa_free_cb_t) service_free);
+    pa_hashmap_free(u->services, NULL, (pa_free_cb_t) service_free);
 
     if (u->main_entry_group)
         avahi_entry_group_free(u->main_entry_group);
diff --git a/src/modules/raop/module-raop-discover.c b/src/modules/raop/module-raop-discover.c
index c7efe9a..9ea2848 100644
--- a/src/modules/raop/module-raop-discover.c
+++ b/src/modules/raop/module-raop-discover.c
@@ -257,7 +257,7 @@ static void browser_cb(
 
         if ((t2 = pa_hashmap_get(u->tunnels, t))) {
             pa_module_unload_request_by_index(u->core, t2->module_index, true);
-            pa_hashmap_remove(u->tunnels, t2);
+            pa_hashmap_remove(u->tunnels, t2, NULL);
             tunnel_free(t2);
         }
     }
@@ -376,12 +376,12 @@ void pa__done(pa_module*m) {
     if (u->tunnels) {
         struct tunnel *t;
 
-        while ((t = pa_hashmap_steal_first(u->tunnels))) {
+        while ((t = pa_hashmap_steal_first(u->tunnels, NULL))) {
             pa_module_unload_request_by_index(u->core, t->module_index, true);
             tunnel_free(t);
         }
 
-        pa_hashmap_free(u->tunnels, NULL);
+        pa_hashmap_free(u->tunnels, NULL, NULL);
     }
 
     pa_xfree(u);
diff --git a/src/modules/rtp/headerlist.c b/src/modules/rtp/headerlist.c
index 9e95e3c..bfc97cd 100644
--- a/src/modules/rtp/headerlist.c
+++ b/src/modules/rtp/headerlist.c
@@ -56,7 +56,7 @@ pa_headerlist* pa_headerlist_new(void) {
 }
 
 void pa_headerlist_free(pa_headerlist* p) {
-    pa_hashmap_free(MAKE_HASHMAP(p), (pa_free_cb_t) header_free);
+    pa_hashmap_free(MAKE_HASHMAP(p), NULL, (pa_free_cb_t) header_free);
 }
 
 int pa_headerlist_puts(pa_headerlist *p, const char *key, const char *value) {
@@ -134,7 +134,7 @@ int pa_headerlist_remove(pa_headerlist *p, const char *key) {
     pa_assert(p);
     pa_assert(key);
 
-    if (!(hdr = pa_hashmap_remove(MAKE_HASHMAP(p), key)))
+    if (!(hdr = pa_hashmap_remove(MAKE_HASHMAP(p), key, NULL)))
         return -1;
 
     header_free(hdr);
diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c
index 7ff2c75..43505fa 100644
--- a/src/modules/rtp/module-rtp-recv.c
+++ b/src/modules/rtp/module-rtp-recv.c
@@ -186,7 +186,7 @@ static void sink_input_kill(pa_sink_input* i) {
     pa_sink_input_assert_ref(i);
     pa_assert_se(s = i->userdata);
 
-    pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin);
+    pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin, NULL);
     session_free(s);
 }
 
@@ -635,7 +635,7 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event
 
     if (goodbye) {
 
-        if ((s = pa_hashmap_remove(u->by_origin, info.origin)))
+        if ((s = pa_hashmap_remove(u->by_origin, info.origin, NULL)))
             session_free(s);
 
         pa_sdp_info_destroy(&info);
@@ -675,7 +675,7 @@ static void check_death_event_cb(pa_mainloop_api *m, pa_time_event *t, const str
         k = pa_atomic_load(&s->timestamp);
 
         if (k + DEATH_TIMEOUT < now.tv_sec) {
-            pa_hashmap_remove(u->by_origin, s->sdp_info.origin);
+            pa_hashmap_remove(u->by_origin, s->sdp_info.origin, NULL);
             session_free(s);
         }
     }
@@ -770,7 +770,7 @@ void pa__done(pa_module*m) {
     pa_sap_context_destroy(&u->sap_context);
 
     if (u->by_origin)
-        pa_hashmap_free(u->by_origin, (pa_free_cb_t) session_free);
+        pa_hashmap_free(u->by_origin, NULL, (pa_free_cb_t) session_free);
 
     pa_xfree(u->sink_name);
     pa_xfree(u);
diff --git a/src/pulse/context.c b/src/pulse/context.c
index 1ba2672..4d3cc0e 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -241,9 +241,9 @@ static void context_free(pa_context *c) {
 #endif
 
     if (c->record_streams)
-        pa_hashmap_free(c->record_streams, NULL);
+        pa_hashmap_free(c->record_streams, NULL, NULL);
     if (c->playback_streams)
-        pa_hashmap_free(c->playback_streams, NULL);
+        pa_hashmap_free(c->playback_streams, NULL, NULL);
 
     if (c->mempool)
         pa_mempool_free(c->mempool);
diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c
index 6e91103..ca3a4f9 100644
--- a/src/pulse/proplist.c
+++ b/src/pulse/proplist.c
@@ -70,7 +70,7 @@ pa_proplist* pa_proplist_new(void) {
 void pa_proplist_free(pa_proplist* p) {
     pa_assert(p);
 
-    pa_hashmap_free(MAKE_HASHMAP(p), (pa_free_cb_t) property_free);
+    pa_hashmap_free(MAKE_HASHMAP(p), NULL, (pa_free_cb_t) property_free);
 }
 
 /** Will accept only valid UTF-8 */
@@ -351,7 +351,7 @@ int pa_proplist_unset(pa_proplist *p, const char *key) {
     if (!pa_proplist_key_valid(key))
         return -1;
 
-    if (!(prop = pa_hashmap_remove(MAKE_HASHMAP(p), key)))
+    if (!(prop = pa_hashmap_remove(MAKE_HASHMAP(p), key, NULL)))
         return -2;
 
     property_free(prop);
@@ -654,7 +654,7 @@ int pa_proplist_contains(pa_proplist *p, const char *key) {
 void pa_proplist_clear(pa_proplist *p) {
     pa_assert(p);
 
-    pa_hashmap_remove_all(MAKE_HASHMAP(p), (pa_free_cb_t) property_free);
+    pa_hashmap_remove_all(MAKE_HASHMAP(p), NULL, (pa_free_cb_t) property_free);
 }
 
 pa_proplist* pa_proplist_copy(const pa_proplist *p) {
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 746179b..1ee1934 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -260,7 +260,8 @@ static void stream_unlink(pa_stream *s) {
         pa_pdispatch_unregister_reply(s->context->pdispatch, s);
 
     if (s->channel_valid) {
-        pa_hashmap_remove((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams, PA_UINT32_TO_PTR(s->channel));
+        pa_hashmap_remove((s->direction == PA_STREAM_RECORD) ? s->context->record_streams : s->context->playback_streams,
+                          PA_UINT32_TO_PTR(s->channel), NULL);
         s->channel = 0;
         s->channel_valid = false;
     }
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index c771cac..6ea1e8f 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -128,10 +128,10 @@ void pa_card_new_data_done(pa_card_new_data *data) {
     pa_proplist_free(data->proplist);
 
     if (data->profiles)
-        pa_hashmap_free(data->profiles, (pa_free_cb_t) pa_card_profile_free);
+        pa_hashmap_free(data->profiles, NULL, (pa_free_cb_t) pa_card_profile_free);
 
     if (data->ports)
-        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
+        pa_hashmap_free(data->ports, NULL, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(data->name);
     pa_xfree(data->active_profile);
@@ -239,10 +239,10 @@ void pa_card_free(pa_card *c) {
     pa_assert(pa_idxset_isempty(c->sources));
     pa_idxset_free(c->sources, NULL);
 
-    pa_hashmap_free(c->ports, (pa_free_cb_t) pa_device_port_unref);
+    pa_hashmap_free(c->ports, NULL, (pa_free_cb_t) pa_device_port_unref);
 
     if (c->profiles)
-        pa_hashmap_free(c->profiles, (pa_free_cb_t) pa_card_profile_free);
+        pa_hashmap_free(c->profiles, NULL, (pa_free_cb_t) pa_card_profile_free);
 
     pa_proplist_free(c->proplist);
     pa_xfree(c->driver);
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index b198822..9fb17dd 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -194,10 +194,10 @@ static void core_free(pa_object *o) {
     pa_idxset_free(c->sink_inputs, NULL);
 
     pa_assert(pa_hashmap_isempty(c->namereg));
-    pa_hashmap_free(c->namereg, NULL);
+    pa_hashmap_free(c->namereg, NULL, NULL);
 
     pa_assert(pa_hashmap_isempty(c->shared));
-    pa_hashmap_free(c->shared, NULL);
+    pa_hashmap_free(c->shared, NULL, NULL);
 
     pa_subscription_free_all(c);
 
diff --git a/src/pulsecore/database-simple.c b/src/pulsecore/database-simple.c
index 0d22e5b..27a1710 100644
--- a/src/pulsecore/database-simple.c
+++ b/src/pulsecore/database-simple.c
@@ -265,7 +265,7 @@ void pa_database_close(pa_database *database) {
     pa_database_sync(database);
     pa_xfree(db->filename);
     pa_xfree(db->tmp_filename);
-    pa_hashmap_free(db->map, (pa_free_cb_t) free_entry);
+    pa_hashmap_free(db->map, NULL, (pa_free_cb_t) free_entry);
     pa_xfree(db);
 }
 
@@ -306,7 +306,7 @@ int pa_database_set(pa_database *database, const pa_datum *key, const pa_datum*
         /* entry with same key exists in hashmap */
         entry *r;
         if (overwrite) {
-            r = pa_hashmap_remove(db->map, key);
+            r = pa_hashmap_remove(db->map, key, NULL);
             pa_hashmap_put(db->map, &e->key, e);
         } else {
             /* won't overwrite, so clean new entry */
@@ -327,7 +327,7 @@ int pa_database_unset(pa_database *database, const pa_datum *key) {
     pa_assert(db);
     pa_assert(key);
 
-    e = pa_hashmap_remove(db->map, key);
+    e = pa_hashmap_remove(db->map, key, NULL);
     if (!e)
         return -1;
 
@@ -337,11 +337,11 @@ int pa_database_unset(pa_database *database, const pa_datum *key) {
 }
 
 int pa_database_clear(pa_database *database) {
-    simple_data *db = (simple_data*)database;
+    simple_data *db = (simple_data*) database;
 
     pa_assert(db);
 
-    pa_hashmap_remove_all(db->map, (pa_free_cb_t) free_entry);
+    pa_hashmap_remove_all(db->map, NULL, (pa_free_cb_t) free_entry);
 
     return 0;
 }
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 8bff5b6..46d617d 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -98,7 +98,7 @@ static void device_port_free(pa_object *o) {
         pa_proplist_free(p->proplist);
 
     if (p->profiles)
-        pa_hashmap_free(p->profiles, NULL);
+        pa_hashmap_free(p->profiles, NULL, NULL);
 
     pa_xfree(p->name);
     pa_xfree(p->description);
diff --git a/src/pulsecore/hashmap.c b/src/pulsecore/hashmap.c
index 0629164..6f3ae68 100644
--- a/src/pulsecore/hashmap.c
+++ b/src/pulsecore/hashmap.c
@@ -35,7 +35,7 @@
 #define NBUCKETS 127
 
 struct hashmap_entry {
-    const void *key;
+    void *key;
     void *value;
 
     struct hashmap_entry *bucket_next, *bucket_previous;
@@ -68,7 +68,7 @@ pa_hashmap *pa_hashmap_new(pa_hash_func_t hash_func, pa_compare_func_t compare_f
     return h;
 }
 
-static void remove_entry(pa_hashmap *h, struct hashmap_entry *e) {
+static void remove_entry(pa_hashmap *h, struct hashmap_entry *e, pa_free_cb_t key_free_cb) {
     pa_assert(h);
     pa_assert(e);
 
@@ -94,6 +94,9 @@ static void remove_entry(pa_hashmap *h, struct hashmap_entry *e) {
         BY_HASH(h)[hash] = e->bucket_next;
     }
 
+    if (key_free_cb)
+        key_free_cb(e->key);
+
     if (pa_flist_push(PA_STATIC_FLIST_GET(entries), e) < 0)
         pa_xfree(e);
 
@@ -101,10 +104,10 @@ static void remove_entry(pa_hashmap *h, struct hashmap_entry *e) {
     h->n_entries--;
 }
 
-void pa_hashmap_free(pa_hashmap *h, pa_free_cb_t free_cb) {
+void pa_hashmap_free(pa_hashmap *h, pa_free_cb_t key_free_cb, pa_free_cb_t value_free_cb) {
     pa_assert(h);
 
-    pa_hashmap_remove_all(h, free_cb);
+    pa_hashmap_remove_all(h, key_free_cb, value_free_cb);
     pa_xfree(h);
 }
 
@@ -120,7 +123,7 @@ static struct hashmap_entry *hash_scan(pa_hashmap *h, unsigned hash, const void
     return NULL;
 }
 
-int pa_hashmap_put(pa_hashmap *h, const void *key, void *value) {
+int pa_hashmap_put(pa_hashmap *h, void *key, void *value) {
     struct hashmap_entry *e;
     unsigned hash;
 
@@ -176,7 +179,7 @@ void* pa_hashmap_get(pa_hashmap *h, const void *key) {
     return e->value;
 }
 
-void* pa_hashmap_remove(pa_hashmap *h, const void *key) {
+void* pa_hashmap_remove(pa_hashmap *h, const void *key, pa_free_cb_t key_free_cb) {
     struct hashmap_entry *e;
     unsigned hash;
     void *data;
@@ -189,21 +192,21 @@ void* pa_hashmap_remove(pa_hashmap *h, const void *key) {
         return NULL;
 
     data = e->value;
-    remove_entry(h, e);
+    remove_entry(h, e, key_free_cb);
 
     return data;
 }
 
-void pa_hashmap_remove_all(pa_hashmap *h, pa_free_cb_t free_cb) {
+void pa_hashmap_remove_all(pa_hashmap *h, pa_free_cb_t key_free_cb, pa_free_cb_t value_free_cb) {
     pa_assert(h);
 
     while (h->iterate_list_head) {
         void *data;
         data = h->iterate_list_head->value;
-        remove_entry(h, h->iterate_list_head);
+        remove_entry(h, h->iterate_list_head, key_free_cb);
 
-        if (free_cb)
-            free_cb(data);
+        if (value_free_cb)
+            value_free_cb(data);
     }
 }
 
@@ -291,7 +294,7 @@ void* pa_hashmap_last(pa_hashmap *h) {
     return h->iterate_list_tail->value;
 }
 
-void* pa_hashmap_steal_first(pa_hashmap *h) {
+void* pa_hashmap_steal_first(pa_hashmap *h, pa_free_cb_t key_free_cb) {
     void *data;
 
     pa_assert(h);
@@ -300,7 +303,7 @@ void* pa_hashmap_steal_first(pa_hashmap *h) {
         return NULL;
 
     data = h->iterate_list_head->value;
-    remove_entry(h, h->iterate_list_head);
+    remove_entry(h, h->iterate_list_head, key_free_cb);
 
     return data;
 }
diff --git a/src/pulsecore/hashmap.h b/src/pulsecore/hashmap.h
index a57fab3..7524099 100644
--- a/src/pulsecore/hashmap.h
+++ b/src/pulsecore/hashmap.h
@@ -36,20 +36,20 @@ typedef struct pa_hashmap pa_hashmap;
 /* Create a new hashmap. Use the specified functions for hashing and comparing objects in the map */
 pa_hashmap *pa_hashmap_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func);
 
-/* Free the hash table. Calls the specified function for every value in the table. The function may be NULL */
-void pa_hashmap_free(pa_hashmap*, pa_free_cb_t free_cb);
+/* Free the hash table. Calls the specified functions for every key and value in the table. The function may be NULL */
+void pa_hashmap_free(pa_hashmap*, pa_free_cb_t key_free_cb, pa_free_cb_t value_free_cbfree_cb);
 
 /* Add an entry to the hashmap. Returns non-zero when the entry already exists */
-int pa_hashmap_put(pa_hashmap *h, const void *key, void *value);
+int pa_hashmap_put(pa_hashmap *h, void *key, void *value);
 
 /* Return an entry from the hashmap */
 void* pa_hashmap_get(pa_hashmap *h, const void *key);
 
 /* Returns the data of the entry while removing */
-void* pa_hashmap_remove(pa_hashmap *h, const void *key);
+void* pa_hashmap_remove(pa_hashmap *h, const void *key, pa_free_cb_t key_free_cb);
 
-/* If free_cb is not NULL, it's called for each entry. */
-void pa_hashmap_remove_all(pa_hashmap *h, pa_free_cb_t free_cb);
+/* If the free_cbs are not NULL, they are called for each key and entry. */
+void pa_hashmap_remove_all(pa_hashmap *h, pa_free_cb_t key_free_cb, pa_free_cb_t value_free_cb);
 
 /* Return the current number of entries of the hashmap */
 unsigned pa_hashmap_size(pa_hashmap *h);
@@ -69,7 +69,7 @@ void *pa_hashmap_iterate(pa_hashmap *h, void **state, const void**key);
 void *pa_hashmap_iterate_backwards(pa_hashmap *h, void **state, const void**key);
 
 /* Remove the oldest entry in the hashmap and return it */
-void *pa_hashmap_steal_first(pa_hashmap *h);
+void *pa_hashmap_steal_first(pa_hashmap *h, pa_free_cb_t key_free_cb);
 
 /* Return the oldest entry in the hashmap */
 void* pa_hashmap_first(pa_hashmap *h);
diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c
index 2d83b72..9ebc66c 100644
--- a/src/pulsecore/memblock.c
+++ b/src/pulsecore/memblock.c
@@ -541,7 +541,7 @@ static void memblock_free(pa_memblock *b) {
 
             pa_mutex_lock(import->mutex);
 
-            pa_assert_se(pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)));
+            pa_assert_se(pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id), NULL));
 
             pa_assert(segment->n_blocks >= 1);
             if (-- segment->n_blocks <= 0)
@@ -701,7 +701,7 @@ static void memblock_replace_import(pa_memblock *b) {
 
     pa_mutex_lock(import->mutex);
 
-    pa_assert_se(pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id)));
+    pa_assert_se(pa_hashmap_remove(import->blocks, PA_UINT32_TO_PTR(b->per_type.imported.id), NULL));
 
     memblock_make_local(b);
 
@@ -929,7 +929,7 @@ static pa_memimport_segment* segment_attach(pa_memimport *i, uint32_t shm_id) {
 static void segment_detach(pa_memimport_segment *seg) {
     pa_assert(seg);
 
-    pa_hashmap_remove(seg->import->segments, PA_UINT32_TO_PTR(seg->memory.id));
+    pa_hashmap_remove(seg->import->segments, PA_UINT32_TO_PTR(seg->memory.id), NULL);
     pa_shm_free(&seg->memory);
 
     if (seg->trap)
@@ -964,8 +964,8 @@ void pa_memimport_free(pa_memimport *i) {
 
     pa_mutex_unlock(i->pool->mutex);
 
-    pa_hashmap_free(i->blocks, NULL);
-    pa_hashmap_free(i->segments, NULL);
+    pa_hashmap_free(i->blocks, NULL, NULL);
+    pa_hashmap_free(i->segments, NULL, NULL);
 
     pa_mutex_free(i->mutex);
 
diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c
index 09ca9fc..8d8964d 100644
--- a/src/pulsecore/modargs.c
+++ b/src/pulsecore/modargs.c
@@ -259,8 +259,8 @@ static void free_func(void *p) {
 void pa_modargs_free(pa_modargs*ma) {
     pa_assert(ma);
 
-    pa_hashmap_free(ma->raw, free_func);
-    pa_hashmap_free(ma->unescaped, free_func);
+    pa_hashmap_free(ma->raw, NULL, free_func);
+    pa_hashmap_free(ma->unescaped, NULL, free_func);
     pa_xfree(ma);
 }
 
diff --git a/src/pulsecore/mutex-win32.c b/src/pulsecore/mutex-win32.c
index 01e8b4a..aa80fb0 100644
--- a/src/pulsecore/mutex-win32.c
+++ b/src/pulsecore/mutex-win32.c
@@ -80,7 +80,7 @@ pa_cond *pa_cond_new(void) {
 void pa_cond_free(pa_cond *c) {
     assert(c);
 
-    pa_hashmap_free(c->wait_events, NULL);
+    pa_hashmap_free(c->wait_events, NULL, NULL);
     pa_xfree(c);
 }
 
@@ -125,7 +125,7 @@ int pa_cond_wait(pa_cond *c, pa_mutex *m) {
 
     pa_mutex_lock(m);
 
-    pa_hashmap_remove(c->wait_events, event);
+    pa_hashmap_remove(c->wait_events, event, NULL);
 
     CloseHandle(event);
 
diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c
index 7704abe..a8a6ff6 100644
--- a/src/pulsecore/namereg.c
+++ b/src/pulsecore/namereg.c
@@ -190,7 +190,7 @@ void pa_namereg_unregister(pa_core *c, const char *name) {
     pa_assert(c);
     pa_assert(name);
 
-    pa_assert_se(e = pa_hashmap_remove(c->namereg, name));
+    pa_assert_se(e = pa_hashmap_remove(c->namereg, name, NULL));
 
     if (c->default_sink == e->data)
         pa_namereg_set_default_sink(c, NULL);
diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c
index 0ff4d83..02deee2 100644
--- a/src/pulsecore/protocol-dbus.c
+++ b/src/pulsecore/protocol-dbus.c
@@ -169,8 +169,8 @@ 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);
-    pa_hashmap_free(p->connections, NULL);
+    pa_hashmap_free(p->objects, NULL, NULL);
+    pa_hashmap_free(p->connections, NULL, NULL);
     pa_idxset_free(p->extensions, NULL);
 
     for (i = 0; i < PA_DBUS_PROTOCOL_HOOK_MAX; ++i)
@@ -649,7 +649,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;
@@ -674,7 +674,7 @@ 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;
@@ -696,7 +696,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;
@@ -827,7 +827,7 @@ int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, con
     if (!(obj_entry = pa_hashmap_get(p->objects, path)))
         return -1;
 
-    if (!(iface_entry = pa_hashmap_remove(obj_entry->interfaces, interface)))
+    if (!(iface_entry = pa_hashmap_remove(obj_entry->interfaces, interface, NULL)))
         return -1;
 
     update_introspection(obj_entry);
@@ -835,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, pa_xfree);
-    pa_hashmap_free(iface_entry->method_handlers, (pa_free_cb_t) method_handler_free);
-    pa_hashmap_free(iface_entry->property_handlers, (pa_free_cb_t) property_handler_free);
+    pa_hashmap_free(iface_entry->method_signatures, NULL, pa_xfree);
+    pa_hashmap_free(iface_entry->method_handlers, NULL, (pa_free_cb_t) method_handler_free);
+    pa_hashmap_free(iface_entry->property_handlers, NULL, (pa_free_cb_t) property_handler_free);
 
     for (i = 0; i < iface_entry->n_signals; ++i) {
         unsigned j;
@@ -859,9 +859,9 @@ int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, con
     if (pa_hashmap_isempty(obj_entry->interfaces)) {
         unregister_object(p, obj_entry);
 
-        pa_hashmap_remove(p->objects, path);
+        pa_hashmap_remove(p->objects, path, NULL);
         pa_xfree(obj_entry->path);
-        pa_hashmap_free(obj_entry->interfaces, NULL);
+        pa_hashmap_free(obj_entry->interfaces, NULL, NULL);
         pa_xfree(obj_entry->introspection);
         pa_xfree(obj_entry);
     }
@@ -941,14 +941,14 @@ int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *
     pa_assert(p);
     pa_assert(conn);
 
-    if (!(conn_entry = pa_hashmap_remove(p->connections, conn)))
+    if (!(conn_entry = pa_hashmap_remove(p->connections, conn, NULL)))
         return -1;
 
     unregister_all_objects(p, conn);
 
     dbus_connection_unref(conn_entry->connection);
     pa_idxset_free(conn_entry->all_signals_objects, pa_xfree);
-    pa_hashmap_free(conn_entry->listening_signals, (pa_free_cb_t) signal_paths_entry_free);
+    pa_hashmap_free(conn_entry->listening_signals, NULL, (pa_free_cb_t) signal_paths_entry_free);
     pa_xfree(conn_entry);
 
     return 0;
@@ -992,7 +992,7 @@ void pa_dbus_protocol_add_signal_listener(
 
         /* 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)))
+        if ((signal_paths_entry = pa_hashmap_remove(conn_entry->listening_signals, signal_name, NULL)))
             signal_paths_entry_free(signal_paths_entry);
         signal_paths_entry = signal_paths_entry_new(signal_name);
 
@@ -1006,7 +1006,7 @@ void pa_dbus_protocol_add_signal_listener(
 
         /* We're not interested in individual signals anymore, so let's empty
          * listening_signals. */
-        pa_hashmap_remove_all(conn_entry->listening_signals, (pa_free_cb_t) signal_paths_entry_free);
+        pa_hashmap_remove_all(conn_entry->listening_signals, NULL, (pa_free_cb_t) signal_paths_entry_free);
 
         for (i = 0; i < n_objects; ++i)
             pa_idxset_put(conn_entry->all_signals_objects, pa_xstrdup(objects[i]), NULL);
@@ -1023,13 +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_remove(conn_entry->listening_signals, signal_name)))
+        if ((signal_paths_entry = pa_hashmap_remove(conn_entry->listening_signals, signal_name, NULL)))
             signal_paths_entry_free(signal_paths_entry);
 
     } else {
         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, (pa_free_cb_t) signal_paths_entry_free);
+        pa_hashmap_remove_all(conn_entry->listening_signals, NULL, (pa_free_cb_t) signal_paths_entry_free);
     }
 }
 
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 9342c1a..42f1e4d 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -5139,7 +5139,7 @@ void pa_native_protocol_unref(pa_native_protocol *p) {
     for (h = 0; h < PA_NATIVE_HOOK_MAX; h++)
         pa_hook_done(&p->hooks[h]);
 
-    pa_hashmap_free(p->extensions, NULL);
+    pa_hashmap_free(p->extensions, NULL, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "native-protocol") >= 0);
 
@@ -5196,7 +5196,7 @@ void pa_native_protocol_remove_ext(pa_native_protocol *p, pa_module *m) {
     pa_assert(PA_REFCNT_VALUE(p) >= 1);
     pa_assert(m);
 
-    pa_assert_se(pa_hashmap_remove(p->extensions, m));
+    pa_assert_se(pa_hashmap_remove(p->extensions, m, NULL));
 }
 
 pa_native_options* pa_native_options_new(void) {
diff --git a/src/pulsecore/shared.c b/src/pulsecore/shared.c
index 368a6c3..ea725d7 100644
--- a/src/pulsecore/shared.c
+++ b/src/pulsecore/shared.c
@@ -91,7 +91,7 @@ int pa_shared_remove(pa_core *c, const char *name) {
     pa_assert(name);
     pa_assert(c->shared);
 
-    if (!(p = pa_hashmap_remove(c->shared, name)))
+    if (!(p = pa_hashmap_remove(c->shared, name, NULL)))
         return -1;
 
     shared_free(p);
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 47f169e..87ddad4 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -241,10 +241,10 @@ void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
         pa_format_info_free(data->format);
 
     if (data->volume_factor_items)
-        pa_hashmap_free(data->volume_factor_items, (pa_free_cb_t) volume_factor_entry_free);
+        pa_hashmap_free(data->volume_factor_items, NULL, (pa_free_cb_t) volume_factor_entry_free);
 
     if (data->volume_factor_sink_items)
-        pa_hashmap_free(data->volume_factor_sink_items, (pa_free_cb_t) volume_factor_entry_free);
+        pa_hashmap_free(data->volume_factor_sink_items, NULL, (pa_free_cb_t) volume_factor_entry_free);
 
     pa_proplist_free(data->proplist);
 }
@@ -766,13 +766,13 @@ static void sink_input_free(pa_object *o) {
         pa_idxset_free(i->direct_outputs, NULL);
 
     if (i->thread_info.direct_outputs)
-        pa_hashmap_free(i->thread_info.direct_outputs, NULL);
+        pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
 
     if (i->volume_factor_items)
-        pa_hashmap_free(i->volume_factor_items, (pa_free_cb_t) volume_factor_entry_free);
+        pa_hashmap_free(i->volume_factor_items, NULL, (pa_free_cb_t) volume_factor_entry_free);
 
     if (i->volume_factor_sink_items)
-        pa_hashmap_free(i->volume_factor_sink_items, (pa_free_cb_t) volume_factor_entry_free);
+        pa_hashmap_free(i->volume_factor_sink_items, NULL, (pa_free_cb_t) volume_factor_entry_free);
 
     pa_xfree(i->driver);
     pa_xfree(i);
@@ -1340,7 +1340,7 @@ int pa_sink_input_remove_volume_factor(pa_sink_input *i, const char *key) {
     pa_assert_ctl_context();
     pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
 
-    v = pa_hashmap_remove(i->volume_factor_items, key);
+    v = pa_hashmap_remove(i->volume_factor_items, key, NULL);
 
     if (!v)
         return -1;
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 3cdabd4..00bc29a 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -142,7 +142,7 @@ void pa_sink_new_data_done(pa_sink_new_data *data) {
     pa_proplist_free(data->proplist);
 
     if (data->ports)
-        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
+        pa_hashmap_free(data->ports, NULL, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(data->name);
     pa_xfree(data->active_port);
@@ -730,7 +730,7 @@ static void sink_free(pa_object *o) {
     }
 
     pa_idxset_free(s->inputs, NULL);
-    pa_hashmap_free(s->thread_info.inputs, (pa_free_cb_t) pa_sink_input_unref);
+    pa_hashmap_free(s->thread_info.inputs, NULL, (pa_free_cb_t) pa_sink_input_unref);
 
     if (s->silence.memblock)
         pa_memblock_unref(s->silence.memblock);
@@ -742,7 +742,7 @@ static void sink_free(pa_object *o) {
         pa_proplist_free(s->proplist);
 
     if (s->ports)
-        pa_hashmap_free(s->ports, (pa_free_cb_t) pa_device_port_unref);
+        pa_hashmap_free(s->ports, NULL, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(s);
 }
@@ -2543,7 +2543,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
                 i->thread_info.sync_next = NULL;
             }
 
-            if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)))
+            if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), NULL))
                 pa_sink_input_unref(i);
 
             pa_sink_invalidate_requested_latency(s, true);
@@ -2626,7 +2626,7 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
             i->thread_info.attached = false;
 
             /* Let's remove the sink input ...*/
-            if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index)))
+            if (pa_hashmap_remove(s->thread_info.inputs, PA_UINT32_TO_PTR(i->index), NULL))
                 pa_sink_input_unref(i);
 
             pa_sink_invalidate_requested_latency(s, true);
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 9c492c1..b14b9c8 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -133,7 +133,7 @@ void pa_source_new_data_done(pa_source_new_data *data) {
     pa_proplist_free(data->proplist);
 
     if (data->ports)
-        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
+        pa_hashmap_free(data->ports, NULL, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(data->name);
     pa_xfree(data->active_port);
@@ -660,7 +660,7 @@ static void source_free(pa_object *o) {
     pa_log_info("Freeing source %u \"%s\"", s->index, s->name);
 
     pa_idxset_free(s->outputs, NULL);
-    pa_hashmap_free(s->thread_info.outputs, (pa_free_cb_t) pa_source_output_unref);
+    pa_hashmap_free(s->thread_info.outputs, NULL, (pa_free_cb_t) pa_source_output_unref);
 
     if (s->silence.memblock)
         pa_memblock_unref(s->silence.memblock);
@@ -672,7 +672,7 @@ static void source_free(pa_object *o) {
         pa_proplist_free(s->proplist);
 
     if (s->ports)
-        pa_hashmap_free(s->ports, (pa_free_cb_t) pa_device_port_unref);
+        pa_hashmap_free(s->ports, NULL, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(s);
 }
@@ -2024,11 +2024,11 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
             o->thread_info.attached = false;
 
             if (o->thread_info.direct_on_input) {
-                pa_hashmap_remove(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index));
+                pa_hashmap_remove(o->thread_info.direct_on_input->thread_info.direct_outputs, PA_UINT32_TO_PTR(o->index), NULL);
                 o->thread_info.direct_on_input = NULL;
             }
 
-            if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index)))
+            if (pa_hashmap_remove(s->thread_info.outputs, PA_UINT32_TO_PTR(o->index), NULL))
                 pa_source_output_unref(o);
 
             pa_source_invalidate_requested_latency(s, true);
-- 
1.8.2.1



More information about the pulseaudio-discuss mailing list