[pulseaudio-commits] 7 commits - src/modules src/pulse src/pulsecore

Tanu Kaskinen tanuk at kemper.freedesktop.org
Fri Feb 15 15:20:47 PST 2013


 src/modules/alsa/alsa-mixer.c                      |   64 +++++--------------
 src/modules/alsa/alsa-sink.c                       |    4 -
 src/modules/alsa/alsa-ucm.c                        |    8 +-
 src/modules/alsa/module-alsa-card.c                |   18 +----
 src/modules/bluetooth/bluetooth-util.c             |    4 -
 src/modules/bluetooth/module-bluetooth-device.c    |    2 
 src/modules/bluetooth/module-bluetooth-discover.c  |    2 
 src/modules/bluetooth/module-bluetooth-proximity.c |   10 ---
 src/modules/dbus/iface-card.c                      |   10 ---
 src/modules/dbus/iface-core.c                      |   68 +++------------------
 src/modules/dbus/iface-device.c                    |   10 ---
 src/modules/dbus/module-dbus-protocol.c            |    9 --
 src/modules/gconf/module-gconf.c                   |   37 ++++++-----
 src/modules/macosx/module-bonjour-publish.c        |    2 
 src/modules/module-augment-properties.c            |   10 ---
 src/modules/module-card-restore.c                  |    4 -
 src/modules/module-combine-sink.c                  |   11 +--
 src/modules/module-console-kit.c                   |    9 --
 src/modules/module-device-manager.c                |   10 +--
 src/modules/module-device-restore.c                |    6 -
 src/modules/module-filter-apply.c                  |    2 
 src/modules/module-role-cork.c                     |   18 +----
 src/modules/module-role-ducking.c                  |   19 ++---
 src/modules/module-stream-restore.c                |   14 ----
 src/modules/module-suspend-on-idle.c               |    6 -
 src/modules/module-systemd-login.c                 |   14 ----
 src/modules/module-udev-detect.c                   |   10 ---
 src/modules/module-zeroconf-discover.c             |    2 
 src/modules/module-zeroconf-publish.c              |   18 +----
 src/modules/raop/module-raop-discover.c            |    2 
 src/modules/rtp/headerlist.c                       |    7 --
 src/modules/rtp/module-rtp-recv.c                  |   17 ++---
 src/pulse/context.c                                |    4 -
 src/pulse/format.c                                 |    4 -
 src/pulse/internal.h                               |    2 
 src/pulse/proplist.c                               |    7 --
 src/pulsecore/card.c                               |   31 ++-------
 src/pulsecore/client.c                             |    4 -
 src/pulsecore/core-scache.c                        |    5 -
 src/pulsecore/core.c                               |   20 +++---
 src/pulsecore/database-simple.c                    |    7 --
 src/pulsecore/device-port.c                        |   15 ----
 src/pulsecore/device-port.h                        |    2 
 src/pulsecore/hashmap.c                            |   25 ++++---
 src/pulsecore/hashmap.h                            |    7 +-
 src/pulsecore/idxset.c                             |   25 ++++---
 src/pulsecore/idxset.h                             |   10 +--
 src/pulsecore/memblock.c                           |    4 -
 src/pulsecore/modargs.c                            |    6 -
 src/pulsecore/module.c                             |    4 -
 src/pulsecore/mutex-win32.c                        |    2 
 src/pulsecore/protocol-cli.c                       |    2 
 src/pulsecore/protocol-dbus.c                      |   66 ++++----------------
 src/pulsecore/protocol-esound.c                    |    2 
 src/pulsecore/protocol-http.c                      |    2 
 src/pulsecore/protocol-native.c                    |   18 ++---
 src/pulsecore/protocol-simple.c                    |    2 
 src/pulsecore/sink-input.c                         |   27 +++-----
 src/pulsecore/sink.c                               |   17 +----
 src/pulsecore/source-output.c                      |   10 +--
 src/pulsecore/source.c                             |   17 +----
 61 files changed, 263 insertions(+), 511 deletions(-)

New commits:
commit 2c666e3e166b2992f114325e3ec53f28f98738df
Author: Tanu Kaskinen <tanuk at iki.fi>
Date:   Tue Feb 12 21:36:57 2013 +0200

    idxset: Add pa_idxset_remove_all()
    
    Slightly nicer than using pa_idxset_steal_first() in a loop.

diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 3c995f8..3f5af34 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -746,19 +746,11 @@ void pa__done(pa_module*m) {
     if (u->jacks)
         pa_hashmap_free(u->jacks, NULL);
 
-    if (u->card && u->card->sinks) {
-        pa_sink *s;
+    if (u->card && u->card->sinks)
+        pa_idxset_remove_all(u->card->sinks, (pa_free_cb_t) pa_alsa_sink_free);
 
-        while ((s = pa_idxset_steal_first(u->card->sinks, NULL)))
-            pa_alsa_sink_free(s);
-    }
-
-    if (u->card && u->card->sources) {
-        pa_source *s;
-
-        while ((s = pa_idxset_steal_first(u->card->sources, NULL)))
-            pa_alsa_source_free(s);
-    }
+    if (u->card && u->card->sources)
+        pa_idxset_remove_all(u->card->sources, (pa_free_cb_t) pa_alsa_source_free);
 
     if (u->card)
         pa_card_free(u->card);
diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c
index 73f65d2..64bc4b3 100644
--- a/src/pulsecore/core-scache.c
+++ b/src/pulsecore/core-scache.c
@@ -282,12 +282,9 @@ int pa_scache_remove_item(pa_core *c, const char *name) {
 }
 
 void pa_scache_free_all(pa_core *c) {
-    pa_scache_entry *e;
-
     pa_assert(c);
 
-    while ((e = pa_idxset_steal_first(c->scache, NULL)))
-        free_entry(e);
+    pa_idxset_remove_all(c->scache, (pa_free_cb_t) free_entry);
 
     if (c->scache_auto_unload_event) {
         c->mainloop->time_free(c->scache_auto_unload_event);
diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c
index fc3ea58..27e4980 100644
--- a/src/pulsecore/idxset.c
+++ b/src/pulsecore/idxset.c
@@ -142,15 +142,7 @@ static void remove_entry(pa_idxset *s, struct idxset_entry *e) {
 void pa_idxset_free(pa_idxset *s, pa_free_cb_t free_cb) {
     pa_assert(s);
 
-    while (s->iterate_list_head) {
-        void *data = s->iterate_list_head->data;
-
-        remove_entry(s, s->iterate_list_head);
-
-        if (free_cb)
-            free_cb(data);
-    }
-
+    pa_idxset_remove_all(s, free_cb);
     pa_xfree(s);
 }
 
@@ -308,6 +300,19 @@ void* pa_idxset_remove_by_data(pa_idxset*s, const void *data, uint32_t *idx) {
     return r;
 }
 
+void pa_idxset_remove_all(pa_idxset *s, pa_free_cb_t free_cb) {
+    pa_assert(s);
+
+    while (s->iterate_list_head) {
+        void *data = s->iterate_list_head->data;
+
+        remove_entry(s, s->iterate_list_head);
+
+        if (free_cb)
+            free_cb(data);
+    }
+}
+
 void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx) {
     unsigned hash;
     struct idxset_entry *e;
diff --git a/src/pulsecore/idxset.h b/src/pulsecore/idxset.h
index 0b12ac1..039e4be 100644
--- a/src/pulsecore/idxset.h
+++ b/src/pulsecore/idxset.h
@@ -73,6 +73,9 @@ void* pa_idxset_remove_by_index(pa_idxset*s, uint32_t idx);
 /* Similar to pa_idxset_get_by_data(), but removes the entry from the idxset */
 void* pa_idxset_remove_by_data(pa_idxset*s, const void *p, uint32_t *idx);
 
+/* If free_cb is not NULL, it's called for each entry. */
+void pa_idxset_remove_all(pa_idxset *s, pa_free_cb_t free_cb);
+
 /* This may be used to iterate through all entries. When called with
    an invalid index value it returns the first entry, otherwise the
    next following. The function is best called with *idx =
diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c
index bf554af..f63c9cd 100644
--- a/src/pulsecore/module.c
+++ b/src/pulsecore/module.c
@@ -203,11 +203,9 @@ void pa_module_unload_by_index(pa_core *c, uint32_t idx, pa_bool_t force) {
 }
 
 void pa_module_unload_all(pa_core *c) {
-    pa_module *m;
     pa_assert(c);
 
-    while ((m = pa_idxset_steal_first(c->modules, NULL)))
-        pa_module_free(m);
+    pa_idxset_remove_all(c->modules, (pa_free_cb_t) pa_module_free);
 
     if (c->module_defer_unload_event) {
         c->mainloop->defer_free(c->module_defer_unload_event);
diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c
index bda2346..17ad902 100644
--- a/src/pulsecore/protocol-dbus.c
+++ b/src/pulsecore/protocol-dbus.c
@@ -974,7 +974,6 @@ void pa_dbus_protocol_add_signal_listener(
         unsigned n_objects) {
     struct connection_entry *conn_entry = NULL;
     struct signal_paths_entry *signal_paths_entry = NULL;
-    char *object_path = NULL;
     unsigned i = 0;
 
     pa_assert(p);
@@ -986,8 +985,7 @@ void pa_dbus_protocol_add_signal_listener(
     /* all_signals_objects will either be emptied or replaced with new objects,
      * so we empty it here unconditionally. If listening_for_all_signals is
      * currently FALSE, the idxset is empty already so this does nothing. */
-    while ((object_path = pa_idxset_steal_first(conn_entry->all_signals_objects, NULL)))
-        pa_xfree(object_path);
+    pa_idxset_remove_all(conn_entry->all_signals_objects, pa_xfree);
 
     if (signal_name) {
         conn_entry->listening_for_all_signals = FALSE;
@@ -1029,13 +1027,8 @@ void pa_dbus_protocol_remove_signal_listener(pa_dbus_protocol *p, DBusConnection
             signal_paths_entry_free(signal_paths_entry);
 
     } else {
-        char *object_path;
-
         conn_entry->listening_for_all_signals = FALSE;
-
-        while ((object_path = pa_idxset_steal_first(conn_entry->all_signals_objects, NULL)))
-            pa_xfree(object_path);
-
+        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);
     }
 }

commit 31ee1a7d54f6ba6eb96a9ae38ad9dfda72c67673
Author: Tanu Kaskinen <tanuk at iki.fi>
Date:   Tue Feb 12 21:36:56 2013 +0200

    hashmap: Add pa_hashmap_remove_all()
    
    Slightly nicer than using pa_hashmap_steal_first() in a loop.

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 881d13d..97f25af 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -3740,7 +3740,7 @@ 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 */
-        while (pa_hashmap_steal_first(ps->paths));
+        pa_hashmap_remove_all(ps->paths, NULL);
         return;
     }
 
diff --git a/src/modules/module-systemd-login.c b/src/modules/module-systemd-login.c
index 2f24711..8ad836e 100644
--- a/src/modules/module-systemd-login.c
+++ b/src/modules/module-systemd-login.c
@@ -141,8 +141,7 @@ static int get_session_list(struct userdata *u) {
         free(sessions);
     }
 
-    while ((o = pa_hashmap_steal_first(u->previous_sessions)))
-        free_session(o);
+    pa_hashmap_remove_all(u->previous_sessions, (pa_free_cb_t) free_session);
 
     return 0;
 }
diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c
index 33b150c..abd551b 100644
--- a/src/pulse/proplist.c
+++ b/src/pulse/proplist.c
@@ -652,11 +652,9 @@ int pa_proplist_contains(pa_proplist *p, const char *key) {
 }
 
 void pa_proplist_clear(pa_proplist *p) {
-    struct property *prop;
     pa_assert(p);
 
-    while ((prop = pa_hashmap_steal_first(MAKE_HASHMAP(p))))
-        property_free(prop);
+    pa_hashmap_remove_all(MAKE_HASHMAP(p), (pa_free_cb_t) property_free);
 }
 
 pa_proplist* pa_proplist_copy(const pa_proplist *p) {
diff --git a/src/pulsecore/database-simple.c b/src/pulsecore/database-simple.c
index 5dd3ac9..91c1b45 100644
--- a/src/pulsecore/database-simple.c
+++ b/src/pulsecore/database-simple.c
@@ -339,12 +339,10 @@ int pa_database_unset(pa_database *database, const pa_datum *key) {
 
 int pa_database_clear(pa_database *database) {
     simple_data *db = (simple_data*)database;
-    entry *e;
 
     pa_assert(db);
 
-    while ((e = pa_hashmap_steal_first(db->map)))
-        free_entry(e);
+    pa_hashmap_remove_all(db->map, (pa_free_cb_t) free_entry);
 
     return 0;
 }
diff --git a/src/pulsecore/hashmap.c b/src/pulsecore/hashmap.c
index cfd08b7..3e1d9f1 100644
--- a/src/pulsecore/hashmap.c
+++ b/src/pulsecore/hashmap.c
@@ -104,15 +104,7 @@ static void remove_entry(pa_hashmap *h, struct hashmap_entry *e) {
 void pa_hashmap_free(pa_hashmap *h, pa_free_cb_t 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);
-
-        if (free_cb)
-            free_cb(data);
-    }
-
+    pa_hashmap_remove_all(h, free_cb);
     pa_xfree(h);
 }
 
@@ -202,6 +194,19 @@ void* pa_hashmap_remove(pa_hashmap *h, const void *key) {
     return data;
 }
 
+void pa_hashmap_remove_all(pa_hashmap *h, pa_free_cb_t 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);
+
+        if (free_cb)
+            free_cb(data);
+    }
+}
+
 void *pa_hashmap_iterate(pa_hashmap *h, void **state, const void **key) {
     struct hashmap_entry *e;
 
diff --git a/src/pulsecore/hashmap.h b/src/pulsecore/hashmap.h
index 8d892b8..59ff12e 100644
--- a/src/pulsecore/hashmap.h
+++ b/src/pulsecore/hashmap.h
@@ -48,6 +48,9 @@ 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);
 
+/* 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);
+
 /* Return the current number of entries of the hashmap */
 unsigned pa_hashmap_size(pa_hashmap *h);
 
diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c
index ffd8ea2..bda2346 100644
--- a/src/pulsecore/protocol-dbus.c
+++ b/src/pulsecore/protocol-dbus.c
@@ -1008,8 +1008,7 @@ void pa_dbus_protocol_add_signal_listener(
 
         /* We're not interested in individual signals anymore, so let's empty
          * listening_signals. */
-        while ((signal_paths_entry = pa_hashmap_steal_first(conn_entry->listening_signals)))
-            signal_paths_entry_free(signal_paths_entry);
+        pa_hashmap_remove_all(conn_entry->listening_signals, (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);
@@ -1037,8 +1036,7 @@ 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 ((signal_paths_entry = pa_hashmap_steal_first(conn_entry->listening_signals)))
-            signal_paths_entry_free(signal_paths_entry);
+        pa_hashmap_remove_all(conn_entry->listening_signals, (pa_free_cb_t) signal_paths_entry_free);
     }
 }
 

commit 061878b5a47ed9aa05d12430b039874b63c29a84
Author: Tanu Kaskinen <tanuk at iki.fi>
Date:   Tue Feb 12 21:36:55 2013 +0200

    idxset: Use pa_free_cb_t instead of pa_free2_cb_t
    
    There were no users for the userdata pointer.

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 395ee2c..881d13d 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -449,7 +449,7 @@ static void setting_free(pa_alsa_setting *s) {
     pa_assert(s);
 
     if (s->options)
-        pa_idxset_free(s->options, NULL, NULL);
+        pa_idxset_free(s->options, NULL);
 
     pa_xfree(s->name);
     pa_xfree(s->description);
@@ -3289,10 +3289,10 @@ static void profile_free(pa_alsa_profile *p) {
     pa_xstrfreev(p->output_mapping_names);
 
     if (p->input_mappings)
-        pa_idxset_free(p->input_mappings, NULL, NULL);
+        pa_idxset_free(p->input_mappings, NULL);
 
     if (p->output_mappings)
-        pa_idxset_free(p->output_mappings, NULL, NULL);
+        pa_idxset_free(p->output_mappings, NULL);
 
     pa_xfree(p);
 }
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 03434f9..69d006e 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -1547,7 +1547,7 @@ static pa_bool_t sink_set_formats(pa_sink *s, pa_idxset *formats) {
             return FALSE;
     }
 
-    pa_idxset_free(u->formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+    pa_idxset_free(u->formats, (pa_free_cb_t) pa_format_info_free);
     u->formats = pa_idxset_new(NULL, NULL);
 
     /* Note: the logic below won't apply if we're using software encoding.
@@ -2455,7 +2455,7 @@ static void userdata_free(struct userdata *u) {
         pa_smoother_free(u->smoother);
 
     if (u->formats)
-        pa_idxset_free(u->formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(u->formats, (pa_free_cb_t) pa_format_info_free);
 
     if (u->rates)
         pa_xfree(u->rates);
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
index 9e62dcb..e01721f 100644
--- a/src/modules/alsa/alsa-ucm.c
+++ b/src/modules/alsa/alsa-ucm.c
@@ -1498,9 +1498,9 @@ static void free_verb(pa_alsa_ucm_verb *verb) {
         PA_LLIST_REMOVE(pa_alsa_ucm_device, verb->devices, di);
         pa_proplist_free(di->proplist);
         if (di->conflicting_devices)
-            pa_idxset_free(di->conflicting_devices, NULL, NULL);
+            pa_idxset_free(di->conflicting_devices, NULL);
         if (di->supported_devices)
-            pa_idxset_free(di->supported_devices, NULL, NULL);
+            pa_idxset_free(di->supported_devices, NULL);
         pa_xfree(di);
     }
 
@@ -1552,7 +1552,7 @@ void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context) {
                 dev->capture_mapping = NULL;
         }
 
-        pa_idxset_free(context->ucm_devices, NULL, NULL);
+        pa_idxset_free(context->ucm_devices, NULL);
     }
 
     if (context->ucm_modifiers) {
@@ -1563,7 +1563,7 @@ void pa_alsa_ucm_mapping_context_free(pa_alsa_ucm_mapping_context *context) {
                 mod->capture_mapping = NULL;
         }
 
-        pa_idxset_free(context->ucm_modifiers, NULL, NULL);
+        pa_idxset_free(context->ucm_modifiers, NULL);
     }
 }
 
diff --git a/src/modules/dbus/module-dbus-protocol.c b/src/modules/dbus/module-dbus-protocol.c
index e77f13b..7e49d93 100644
--- a/src/modules/dbus/module-dbus-protocol.c
+++ b/src/modules/dbus/module-dbus-protocol.c
@@ -585,7 +585,6 @@ fail:
 
 void pa__done(pa_module *m) {
     struct userdata *u;
-    struct connection *c;
 
     pa_assert(m);
 
@@ -595,12 +594,8 @@ void pa__done(pa_module *m) {
     if (u->core_iface)
         pa_dbusiface_core_free(u->core_iface);
 
-    if (u->connections) {
-        while ((c = pa_idxset_steal_first(u->connections, NULL)))
-            connection_free(c);
-
-        pa_idxset_free(u->connections, NULL, NULL);
-    }
+    if (u->connections)
+        pa_idxset_free(u->connections, (pa_free_cb_t) connection_free);
 
     /* This must not be called before the connections are freed, because if
      * there are any connections left, they will emit the
diff --git a/src/modules/module-combine-sink.c b/src/modules/module-combine-sink.c
index dd38009..7d660f0 100644
--- a/src/modules/module-combine-sink.c
+++ b/src/modules/module-combine-sink.c
@@ -550,6 +550,7 @@ static void sink_input_kill_cb(pa_sink_input *i) {
     pa_assert_se(o = i->userdata);
 
     pa_module_unload_request(o->userdata->module, TRUE);
+    pa_idxset_remove_by_data(o->userdata->outputs, o, NULL);
     output_free(o);
 }
 
@@ -1107,6 +1108,7 @@ static pa_hook_result_t sink_unlink_hook_cb(pa_core *c, pa_sink *s, struct userd
     if (!u->automatic)
         u->unlinked_slaves = pa_strlist_prepend(u->unlinked_slaves, s->name);
 
+    pa_idxset_remove_by_data(u->outputs, o, NULL);
     output_free(o);
 
     return PA_HOOK_OK;
@@ -1368,7 +1370,6 @@ fail:
 
 void pa__done(pa_module*m) {
     struct userdata *u;
-    struct output *o;
 
     pa_assert(m);
 
@@ -1386,12 +1387,8 @@ void pa__done(pa_module*m) {
     if (u->sink_state_changed_slot)
         pa_hook_slot_free(u->sink_state_changed_slot);
 
-    if (u->outputs) {
-        while ((o = pa_idxset_first(u->outputs, NULL)))
-            output_free(o);
-
-        pa_idxset_free(u->outputs, NULL, NULL);
-    }
+    if (u->outputs)
+        pa_idxset_free(u->outputs, (pa_free_cb_t) output_free);
 
     if (u->sink)
         pa_sink_unlink(u->sink);
diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c
index 1207824..207870d 100644
--- a/src/modules/module-device-manager.c
+++ b/src/modules/module-device-manager.c
@@ -1699,7 +1699,7 @@ void pa__done(pa_module*m) {
     }
 
     if (u->subscribed)
-        pa_idxset_free(u->subscribed, NULL, NULL);
+        pa_idxset_free(u->subscribed, NULL);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c
index 2a666ac..8360a05 100644
--- a/src/modules/module-device-restore.c
+++ b/src/modules/module-device-restore.c
@@ -351,7 +351,7 @@ static struct perportentry* perportentry_new(pa_bool_t add_pcm_format) {
 static void perportentry_free(struct perportentry* e) {
     pa_assert(e);
 
-    pa_idxset_free(e->formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+    pa_idxset_free(e->formats, (pa_free_cb_t) pa_format_info_free);
     pa_xfree(e);
 }
 
@@ -1151,7 +1151,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                 e = perportentry_new(FALSE);
             else {
                 /* Clean out any saved formats */
-                pa_idxset_free(e->formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+                pa_idxset_free(e->formats, (pa_free_cb_t) pa_format_info_free);
                 e->formats = pa_idxset_new(NULL, NULL);
             }
 
@@ -1338,7 +1338,7 @@ void pa__done(pa_module*m) {
     }
 
     if (u->subscribed)
-        pa_idxset_free(u->subscribed, NULL, NULL);
+        pa_idxset_free(u->subscribed, NULL);
 
     pa_xfree(u);
 }
diff --git a/src/modules/module-role-cork.c b/src/modules/module-role-cork.c
index 77bac1e..6e6ea72 100644
--- a/src/modules/module-role-cork.c
+++ b/src/modules/module-role-cork.c
@@ -283,23 +283,17 @@ fail:
 
 void pa__done(pa_module *m) {
     struct userdata* u;
-    char *role;
 
     pa_assert(m);
 
     if (!(u = m->userdata))
         return;
 
-    if (u->trigger_roles) {
-        while ((role = pa_idxset_steal_first(u->trigger_roles, NULL)))
-            pa_xfree(role);
-        pa_idxset_free(u->trigger_roles, NULL, NULL);
-    }
-    if (u->cork_roles) {
-        while ((role = pa_idxset_steal_first(u->cork_roles, NULL)))
-            pa_xfree(role);
-        pa_idxset_free(u->cork_roles, NULL, NULL);
-    }
+    if (u->trigger_roles)
+        pa_idxset_free(u->trigger_roles, pa_xfree);
+
+    if (u->cork_roles)
+        pa_idxset_free(u->cork_roles, pa_xfree);
 
     if (u->sink_input_put_slot)
         pa_hook_slot_free(u->sink_input_put_slot);
diff --git a/src/modules/module-role-ducking.c b/src/modules/module-role-ducking.c
index 8ea43ad..9947871 100644
--- a/src/modules/module-role-ducking.c
+++ b/src/modules/module-role-ducking.c
@@ -286,28 +286,23 @@ fail:
 void pa__done(pa_module *m) {
     struct userdata* u;
     pa_sink_input *i;
-    char *role;
 
     pa_assert(m);
 
     if (!(u = m->userdata))
         return;
 
-    if (u->trigger_roles) {
-        while ((role = pa_idxset_steal_first(u->trigger_roles, NULL)))
-            pa_xfree(role);
-        pa_idxset_free(u->trigger_roles, NULL, NULL);
-    }
-    if (u->ducking_roles) {
-        while ((role = pa_idxset_steal_first(u->ducking_roles, NULL)))
-            pa_xfree(role);
-        pa_idxset_free(u->ducking_roles, NULL, NULL);
-    }
+    if (u->trigger_roles)
+        pa_idxset_free(u->trigger_roles, pa_xfree);
+
+    if (u->ducking_roles)
+        pa_idxset_free(u->ducking_roles, pa_xfree);
+
     if (u->ducked_inputs) {
         while ((i = pa_idxset_steal_first(u->ducked_inputs, NULL)))
             pa_sink_input_remove_volume_factor(i, u->name);
 
-        pa_idxset_free(u->ducked_inputs, NULL, NULL);
+        pa_idxset_free(u->ducked_inputs, NULL);
     }
 
     if (u->sink_input_put_slot)
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 64bb241..23f4780 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -2549,7 +2549,7 @@ void pa__done(pa_module*m) {
     }
 
     if (u->subscribed)
-        pa_idxset_free(u->subscribed, NULL, NULL);
+        pa_idxset_free(u->subscribed, NULL);
 
     pa_xfree(u);
 }
diff --git a/src/pulse/format.c b/src/pulse/format.c
index 542d119..b909eea 100644
--- a/src/pulse/format.c
+++ b/src/pulse/format.c
@@ -100,10 +100,6 @@ void pa_format_info_free(pa_format_info *f) {
     pa_xfree(f);
 }
 
-void pa_format_info_free2(pa_format_info *f, void *userdata) {
-    pa_format_info_free(f);
-}
-
 int pa_format_info_valid(const pa_format_info *f) {
     return (f->encoding >= 0 && f->encoding < PA_ENCODING_MAX && f->plist != NULL);
 }
diff --git a/src/pulse/internal.h b/src/pulse/internal.h
index 833653d..e72e285 100644
--- a/src/pulse/internal.h
+++ b/src/pulse/internal.h
@@ -305,8 +305,6 @@ void pa_ext_device_manager_command(pa_context *c, uint32_t tag, pa_tagstruct *t)
 void pa_ext_device_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
 void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t);
 
-void pa_format_info_free2(pa_format_info *f, void *userdata);
-
 pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api*m);
 
 #endif
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index c3bb7eb..c05fc7a 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -233,9 +233,9 @@ void pa_card_free(pa_card *c) {
     pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);
 
     pa_assert(pa_idxset_isempty(c->sinks));
-    pa_idxset_free(c->sinks, NULL, NULL);
+    pa_idxset_free(c->sinks, NULL);
     pa_assert(pa_idxset_isempty(c->sources));
-    pa_idxset_free(c->sources, NULL, NULL);
+    pa_idxset_free(c->sources, NULL);
 
     pa_hashmap_free(c->ports, (pa_free_cb_t) pa_device_port_unref);
 
diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c
index c956b10..a8fde9f 100644
--- a/src/pulsecore/client.c
+++ b/src/pulsecore/client.c
@@ -103,9 +103,9 @@ void pa_client_free(pa_client *c) {
     pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index);
 
     pa_assert(pa_idxset_isempty(c->sink_inputs));
-    pa_idxset_free(c->sink_inputs, NULL, NULL);
+    pa_idxset_free(c->sink_inputs, NULL);
     pa_assert(pa_idxset_isempty(c->source_outputs));
-    pa_idxset_free(c->source_outputs, NULL, NULL);
+    pa_idxset_free(c->source_outputs, NULL);
 
     pa_proplist_free(c->proplist);
     pa_xfree(c->driver);
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index 37f3fae..98ad16e 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -170,28 +170,28 @@ static void core_free(pa_object *o) {
      * we get here */
 
     pa_assert(pa_idxset_isempty(c->scache));
-    pa_idxset_free(c->scache, NULL, NULL);
+    pa_idxset_free(c->scache, NULL);
 
     pa_assert(pa_idxset_isempty(c->modules));
-    pa_idxset_free(c->modules, NULL, NULL);
+    pa_idxset_free(c->modules, NULL);
 
     pa_assert(pa_idxset_isempty(c->clients));
-    pa_idxset_free(c->clients, NULL, NULL);
+    pa_idxset_free(c->clients, NULL);
 
     pa_assert(pa_idxset_isempty(c->cards));
-    pa_idxset_free(c->cards, NULL, NULL);
+    pa_idxset_free(c->cards, NULL);
 
     pa_assert(pa_idxset_isempty(c->sinks));
-    pa_idxset_free(c->sinks, NULL, NULL);
+    pa_idxset_free(c->sinks, NULL);
 
     pa_assert(pa_idxset_isempty(c->sources));
-    pa_idxset_free(c->sources, NULL, NULL);
+    pa_idxset_free(c->sources, NULL);
 
     pa_assert(pa_idxset_isempty(c->source_outputs));
-    pa_idxset_free(c->source_outputs, NULL, NULL);
+    pa_idxset_free(c->source_outputs, NULL);
 
     pa_assert(pa_idxset_isempty(c->sink_inputs));
-    pa_idxset_free(c->sink_inputs, NULL, NULL);
+    pa_idxset_free(c->sink_inputs, NULL);
 
     pa_assert(pa_hashmap_isempty(c->namereg));
     pa_hashmap_free(c->namereg, NULL);
diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c
index 2b6af90..fc3ea58 100644
--- a/src/pulsecore/idxset.c
+++ b/src/pulsecore/idxset.c
@@ -139,7 +139,7 @@ static void remove_entry(pa_idxset *s, struct idxset_entry *e) {
     s->n_entries--;
 }
 
-void pa_idxset_free(pa_idxset *s, pa_free2_cb_t free_cb, void *userdata) {
+void pa_idxset_free(pa_idxset *s, pa_free_cb_t free_cb) {
     pa_assert(s);
 
     while (s->iterate_list_head) {
@@ -148,7 +148,7 @@ void pa_idxset_free(pa_idxset *s, pa_free2_cb_t free_cb, void *userdata) {
         remove_entry(s, s->iterate_list_head);
 
         if (free_cb)
-            free_cb(data, userdata);
+            free_cb(data);
     }
 
     pa_xfree(s);
diff --git a/src/pulsecore/idxset.h b/src/pulsecore/idxset.h
index 2d01fb4..0b12ac1 100644
--- a/src/pulsecore/idxset.h
+++ b/src/pulsecore/idxset.h
@@ -25,6 +25,8 @@
 
 #include <inttypes.h>
 
+#include <pulse/def.h>
+
 #include <pulsecore/macro.h>
 
 /* A combination of a set and a dynamic array. Entries are indexable
@@ -35,9 +37,6 @@
 /* A special index value denoting the invalid index. */
 #define PA_IDXSET_INVALID ((uint32_t) -1)
 
-/* Similar to pa_free_cb_t, but takes a userdata argument */
-typedef void (*pa_free2_cb_t)(void *p, void *userdata);
-
 /* Generic implementations for hash and comparison functions. Just
  * compares the pointer or calculates the hash value directly from the
  * pointer value. */
@@ -57,7 +56,7 @@ typedef struct pa_idxset pa_idxset;
 pa_idxset* pa_idxset_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func);
 
 /* Free the idxset. When the idxset is not empty the specified function is called for every entry contained */
-void pa_idxset_free(pa_idxset *s, pa_free2_cb_t free_cb, void *userdata);
+void pa_idxset_free(pa_idxset *s, pa_free_cb_t free_cb);
 
 /* Store a new item in the idxset. The index of the item is returned in *idx */
 int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx);
diff --git a/src/pulsecore/protocol-cli.c b/src/pulsecore/protocol-cli.c
index da64874..cc6eeee 100644
--- a/src/pulsecore/protocol-cli.c
+++ b/src/pulsecore/protocol-cli.c
@@ -134,7 +134,7 @@ void pa_cli_protocol_unref(pa_cli_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         cli_unlink(p, c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "cli-protocol") >= 0);
 
diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c
index dab4678..ffd8ea2 100644
--- a/src/pulsecore/protocol-dbus.c
+++ b/src/pulsecore/protocol-dbus.c
@@ -171,7 +171,7 @@ void pa_dbus_protocol_unref(pa_dbus_protocol *p) {
 
     pa_hashmap_free(p->objects, NULL);
     pa_hashmap_free(p->connections, NULL);
-    pa_idxset_free(p->extensions, NULL, NULL);
+    pa_idxset_free(p->extensions, NULL);
 
     for (i = 0; i < PA_DBUS_PROTOCOL_HOOK_MAX; ++i)
         pa_hook_done(&p->hooks[i]);
@@ -928,22 +928,15 @@ static struct signal_paths_entry *signal_paths_entry_new(const char *signal_name
 }
 
 static void signal_paths_entry_free(struct signal_paths_entry *e) {
-    char *path = NULL;
-
     pa_assert(e);
 
     pa_xfree(e->signal);
-
-    while ((path = pa_idxset_steal_first(e->paths, NULL)))
-        pa_xfree(path);
-
-    pa_idxset_free(e->paths, NULL, NULL);
+    pa_idxset_free(e->paths, pa_xfree);
     pa_xfree(e);
 }
 
 int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *conn) {
     struct connection_entry *conn_entry = NULL;
-    char *object_path = NULL;
 
     pa_assert(p);
     pa_assert(conn);
@@ -954,12 +947,7 @@ int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *
     unregister_all_objects(p, conn);
 
     dbus_connection_unref(conn_entry->connection);
-
-    while ((object_path = pa_idxset_steal_first(conn_entry->all_signals_objects, NULL)))
-        pa_xfree(object_path);
-
-    pa_idxset_free(conn_entry->all_signals_objects, NULL, NULL);
-
+    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_xfree(conn_entry);
 
diff --git a/src/pulsecore/protocol-esound.c b/src/pulsecore/protocol-esound.c
index ce50084..52aa2c5 100644
--- a/src/pulsecore/protocol-esound.c
+++ b/src/pulsecore/protocol-esound.c
@@ -1627,7 +1627,7 @@ void pa_esound_protocol_unref(pa_esound_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         connection_unlink(c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "esound-protocol") >= 0);
 
diff --git a/src/pulsecore/protocol-http.c b/src/pulsecore/protocol-http.c
index d745634..400150f 100644
--- a/src/pulsecore/protocol-http.c
+++ b/src/pulsecore/protocol-http.c
@@ -786,7 +786,7 @@ void pa_http_protocol_unref(pa_http_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         connection_unlink(c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_strlist_free(p->servers);
 
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 6a9379e..a4ee920 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -1222,7 +1222,7 @@ static playback_stream* playback_stream_new(
 
 out:
     if (formats)
-        pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
 
     return s;
 }
@@ -1340,8 +1340,8 @@ static void native_connection_free(pa_object *o) {
 
     native_connection_unlink(c);
 
-    pa_idxset_free(c->record_streams, NULL, NULL);
-    pa_idxset_free(c->output_streams, NULL, NULL);
+    pa_idxset_free(c->record_streams, NULL);
+    pa_idxset_free(c->output_streams, NULL);
 
     pa_pdispatch_unref(c->pdispatch);
     pa_pstream_unref(c->pstream);
@@ -2193,7 +2193,7 @@ finish:
     if (p)
         pa_proplist_free(p);
     if (formats)
-        pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
 }
 
 static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -2508,7 +2508,7 @@ finish:
     if (p)
         pa_proplist_free(p);
     if (formats)
-        pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
 }
 
 static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -3143,7 +3143,7 @@ static void sink_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sin
             pa_tagstruct_put_format_info(t, f);
         }
 
-        pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
     }
 }
 
@@ -3213,7 +3213,7 @@ static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_s
             pa_tagstruct_put_format_info(t, f);
         }
 
-        pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
     }
 }
 
@@ -5093,7 +5093,7 @@ void pa_native_protocol_unref(pa_native_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         native_connection_unlink(c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_strlist_free(p->servers);
 
diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c
index 8d8f5b8..9242e68 100644
--- a/src/pulsecore/protocol-simple.c
+++ b/src/pulsecore/protocol-simple.c
@@ -690,7 +690,7 @@ void pa_simple_protocol_unref(pa_simple_protocol *p) {
     while ((c = pa_idxset_first(p->connections, NULL)))
         connection_unlink(c);
 
-    pa_idxset_free(p->connections, NULL, NULL);
+    pa_idxset_free(p->connections, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "simple-protocol") >= 0);
 
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 165faa7..519f47e 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -198,12 +198,12 @@ pa_bool_t pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink
             data->sink = s;
             data->save_sink = save;
             if (data->nego_formats)
-                pa_idxset_free(data->nego_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+                pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
             data->nego_formats = formats;
         } else {
             /* Sink doesn't support any of the formats requested by the client */
             if (formats)
-                pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+                pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
             ret = FALSE;
         }
     }
@@ -216,7 +216,7 @@ pa_bool_t pa_sink_input_new_data_set_formats(pa_sink_input_new_data *data, pa_id
     pa_assert(formats);
 
     if (data->req_formats)
-        pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
 
     data->req_formats = formats;
 
@@ -232,10 +232,10 @@ void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
     pa_assert(data);
 
     if (data->req_formats)
-        pa_idxset_free(data->req_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(data->req_formats, (pa_free_cb_t) pa_format_info_free);
 
     if (data->nego_formats)
-        pa_idxset_free(data->nego_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
 
     if (data->format)
         pa_format_info_free(data->format);
@@ -738,7 +738,7 @@ static void sink_input_free(pa_object *o) {
         pa_proplist_free(i->proplist);
 
     if (i->direct_outputs)
-        pa_idxset_free(i->direct_outputs, NULL, NULL);
+        pa_idxset_free(i->direct_outputs, NULL);
 
     if (i->thread_info.direct_outputs)
         pa_hashmap_free(i->thread_info.direct_outputs, NULL);
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index d8fb5fe..6ebe956 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -730,7 +730,7 @@ static void sink_free(pa_object *o) {
         s->monitor_source = NULL;
     }
 
-    pa_idxset_free(s->inputs, NULL, NULL);
+    pa_idxset_free(s->inputs, NULL);
     pa_hashmap_free(s->thread_info.inputs, (pa_free_cb_t) pa_sink_input_unref);
 
     if (s->silence.memblock)
@@ -3734,7 +3734,7 @@ pa_bool_t pa_sink_check_format(pa_sink *s, pa_format_info *f)
             }
         }
 
-        pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
     }
 
     return ret;
@@ -3764,7 +3764,7 @@ pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats) {
 
 done:
     if (sink_formats)
-        pa_idxset_free(sink_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(sink_formats, (pa_free_cb_t) pa_format_info_free);
 
     return out_formats;
 }
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index 0f1a946..d942419 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -143,12 +143,12 @@ pa_bool_t pa_source_output_new_data_set_source(pa_source_output_new_data *data,
             data->source = s;
             data->save_source = save;
             if (data->nego_formats)
-                pa_idxset_free(data->nego_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+                pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
             data->nego_formats = formats;
         } else {
             /* Source doesn't support any of the formats requested by the client */
             if (formats)
-                pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+                pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
             ret = FALSE;
         }
     }
@@ -161,7 +161,7 @@ pa_bool_t pa_source_output_new_data_set_formats(pa_source_output_new_data *data,
     pa_assert(formats);
 
     if (data->req_formats)
-        pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
 
     data->req_formats = formats;
 
@@ -177,10 +177,10 @@ void pa_source_output_new_data_done(pa_source_output_new_data *data) {
     pa_assert(data);
 
     if (data->req_formats)
-        pa_idxset_free(data->req_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(data->req_formats, (pa_free_cb_t) pa_format_info_free);
 
     if (data->nego_formats)
-        pa_idxset_free(data->nego_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
 
     if (data->format)
         pa_format_info_free(data->format);
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index f72d667..4e4cd67 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -659,7 +659,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, NULL);
+    pa_idxset_free(s->outputs, NULL);
     pa_hashmap_free(s->thread_info.outputs, (pa_free_cb_t) pa_source_output_unref);
 
     if (s->silence.memblock)
@@ -2801,7 +2801,7 @@ pa_bool_t pa_source_check_format(pa_source *s, pa_format_info *f)
             }
         }
 
-        pa_idxset_free(formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(formats, (pa_free_cb_t) pa_format_info_free);
     }
 
     return ret;
@@ -2831,7 +2831,7 @@ pa_idxset* pa_source_check_formats(pa_source *s, pa_idxset *in_formats) {
 
 done:
     if (source_formats)
-        pa_idxset_free(source_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+        pa_idxset_free(source_formats, (pa_free_cb_t) pa_format_info_free);
 
     return out_formats;
 }

commit 43e786800850938fd68877634ce6288b04bd45a7
Author: Tanu Kaskinen <tanuk at iki.fi>
Date:   Tue Feb 12 21:36:54 2013 +0200

    device-port: Remove pa_device_port_hashmap_free()

diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index 33b2afa..f6f6da6 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -2432,7 +2432,7 @@ static pa_hook_result_t uuid_added_cb(pa_bluetooth_discovery *y, const struct pa
 
     pa_card_add_ports(u->card, new_ports);
 
-    pa_device_port_hashmap_free(new_ports);
+    pa_hashmap_free(new_ports, (pa_free_cb_t) pa_device_port_unref);
 
     return PA_HOOK_OK;
 }
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index 560e36e..c3bb7eb 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -129,7 +129,7 @@ void pa_card_new_data_done(pa_card_new_data *data) {
         pa_hashmap_free(data->profiles, (pa_free_cb_t) pa_card_profile_free);
 
     if (data->ports)
-        pa_device_port_hashmap_free(data->ports);
+        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(data->name);
     pa_xfree(data->active_profile);
@@ -237,7 +237,7 @@ void pa_card_free(pa_card *c) {
     pa_assert(pa_idxset_isempty(c->sources));
     pa_idxset_free(c->sources, NULL, NULL);
 
-    pa_device_port_hashmap_free(c->ports);
+    pa_hashmap_free(c->ports, (pa_free_cb_t) pa_device_port_unref);
 
     if (c->profiles)
         pa_hashmap_free(c->profiles, (pa_free_cb_t) pa_card_profile_free);
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 5c7a5bb..e0f9560 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -89,12 +89,6 @@ pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *des
     return p;
 }
 
-void pa_device_port_hashmap_free(pa_hashmap *h) {
-    pa_assert(h);
-
-    pa_hashmap_free(h, (pa_free_cb_t) pa_device_port_unref);
-}
-
 void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) {
     uint32_t state;
     pa_core *core;
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
index cea00e6..40306f5 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -65,8 +65,6 @@ PA_DECLARE_PUBLIC_CLASS(pa_device_port);
 
 pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *description, size_t extra);
 
-void pa_device_port_hashmap_free(pa_hashmap *h);
-
 /* The port's available status has changed */
 void pa_device_port_set_available(pa_device_port *p, pa_port_available_t available);
 
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 171072e..d8fb5fe 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_device_port_hashmap_free(data->ports);
+        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(data->name);
     pa_xfree(data->active_port);
@@ -743,7 +743,7 @@ static void sink_free(pa_object *o) {
         pa_proplist_free(s->proplist);
 
     if (s->ports)
-        pa_device_port_hashmap_free(s->ports);
+        pa_hashmap_free(s->ports, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(s);
 }
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 5c12137..f72d667 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_device_port_hashmap_free(data->ports);
+        pa_hashmap_free(data->ports, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(data->name);
     pa_xfree(data->active_port);
@@ -672,7 +672,7 @@ static void source_free(pa_object *o) {
         pa_proplist_free(s->proplist);
 
     if (s->ports)
-        pa_device_port_hashmap_free(s->ports);
+        pa_hashmap_free(s->ports, (pa_free_cb_t) pa_device_port_unref);
 
     pa_xfree(s);
 }

commit 8872c238ba6748c76455ecc6827b83ebcb1dd469
Author: Tanu Kaskinen <tanuk at iki.fi>
Date:   Tue Feb 12 21:36:53 2013 +0200

    hashmap: Use pa_free_cb_t instead of pa_free2_cb_t
    
    The previous patch removed module-gconf's dependency on the userdata
    pointer of the free callback, and that was the only place where the
    userdata pointer of pa_free2_cb_t was used, so now there's no need for
    pa_free2_cb_t in pa_hashmap_free(). Using pa_free_cb_t instead allows
    removing a significant amount of repetitive code.

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 761aae1..395ee2c 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, NULL);
+        pa_hashmap_free(ps->paths, NULL);
 
     pa_xfree(ps);
 }
@@ -3300,50 +3300,20 @@ static void profile_free(pa_alsa_profile *p) {
 void pa_alsa_profile_set_free(pa_alsa_profile_set *ps) {
     pa_assert(ps);
 
-    if (ps->input_paths) {
-        pa_alsa_path *p;
-
-        while ((p = pa_hashmap_steal_first(ps->input_paths)))
-            pa_alsa_path_free(p);
-
-        pa_hashmap_free(ps->input_paths, NULL, NULL);
-    }
-
-    if (ps->output_paths) {
-        pa_alsa_path *p;
-
-        while ((p = pa_hashmap_steal_first(ps->output_paths)))
-            pa_alsa_path_free(p);
-
-        pa_hashmap_free(ps->output_paths, NULL, NULL);
-    }
+    if (ps->input_paths)
+        pa_hashmap_free(ps->input_paths, (pa_free_cb_t) pa_alsa_path_free);
 
-    if (ps->profiles) {
-        pa_alsa_profile *p;
+    if (ps->output_paths)
+        pa_hashmap_free(ps->output_paths, (pa_free_cb_t) pa_alsa_path_free);
 
-        while ((p = pa_hashmap_steal_first(ps->profiles)))
-            profile_free(p);
-
-        pa_hashmap_free(ps->profiles, NULL, NULL);
-    }
+    if (ps->profiles)
+        pa_hashmap_free(ps->profiles, (pa_free_cb_t) profile_free);
 
-    if (ps->mappings) {
-        pa_alsa_mapping *m;
-
-        while ((m = pa_hashmap_steal_first(ps->mappings)))
-            mapping_free(m);
+    if (ps->mappings)
+        pa_hashmap_free(ps->mappings, (pa_free_cb_t) mapping_free);
 
-        pa_hashmap_free(ps->mappings, NULL, NULL);
-    }
-
-    if (ps->decibel_fixes) {
-        pa_alsa_decibel_fix *db_fix;
-
-        while ((db_fix = pa_hashmap_steal_first(ps->decibel_fixes)))
-            decibel_fix_free(db_fix);
-
-        pa_hashmap_free(ps->decibel_fixes, NULL, NULL);
-    }
+    if (ps->decibel_fixes)
+        pa_hashmap_free(ps->decibel_fixes, (pa_free_cb_t) decibel_fix_free);
 
     pa_xfree(ps);
 }
@@ -4415,8 +4385,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, NULL);
-    pa_hashmap_free(broken_outputs, NULL, NULL);
+    pa_hashmap_free(broken_inputs, NULL);
+    pa_hashmap_free(broken_outputs, NULL);
 
     ps->probed = TRUE;
 }
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 366f4ba..3c995f8 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -744,7 +744,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, NULL);
+        pa_hashmap_free(u->jacks, NULL);
 
     if (u->card && u->card->sinks) {
         pa_sink *s;
diff --git a/src/modules/bluetooth/bluetooth-util.c b/src/modules/bluetooth/bluetooth-util.c
index 8fa1631..7a9f7e9 100644
--- a/src/modules/bluetooth/bluetooth-util.c
+++ b/src/modules/bluetooth/bluetooth-util.c
@@ -1736,12 +1736,12 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) {
 
     if (y->devices) {
         remove_all_devices(y);
-        pa_hashmap_free(y->devices, NULL, NULL);
+        pa_hashmap_free(y->devices, NULL);
     }
 
     if (y->transports) {
         pa_assert(pa_hashmap_isempty(y->transports));
-        pa_hashmap_free(y->transports, NULL, NULL);
+        pa_hashmap_free(y->transports, NULL);
     }
 
     if (y->connection) {
diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c
index eb59beb..cbd56cc 100644
--- a/src/modules/bluetooth/module-bluetooth-discover.c
+++ b/src/modules/bluetooth/module-bluetooth-discover.c
@@ -184,7 +184,7 @@ void pa__done(pa_module* m) {
             pa_xfree(mi);
         }
 
-        pa_hashmap_free(u->hashmap, NULL, NULL);
+        pa_hashmap_free(u->hashmap, NULL);
     }
 
     if (u->modargs)
diff --git a/src/modules/bluetooth/module-bluetooth-proximity.c b/src/modules/bluetooth/module-bluetooth-proximity.c
index 7f90951..b55dfdb 100644
--- a/src/modules/bluetooth/module-bluetooth-proximity.c
+++ b/src/modules/bluetooth/module-bluetooth-proximity.c
@@ -466,14 +466,8 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
-    if (u->bondings) {
-        struct bonding *b;
-
-        while ((b = pa_hashmap_steal_first(u->bondings)))
-            bonding_free(b);
-
-        pa_hashmap_free(u->bondings, NULL, NULL);
-    }
+    if (u->bondings)
+        pa_hashmap_free(u->bondings, (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 1313e71..945f5bb 100644
--- a/src/modules/dbus/iface-card.c
+++ b/src/modules/dbus/iface-card.c
@@ -543,14 +543,6 @@ pa_dbusiface_card *pa_dbusiface_card_new(pa_dbusiface_core *core, pa_card *card)
     return c;
 }
 
-static void profile_free_cb(void *p, void *userdata) {
-    pa_dbusiface_card_profile *profile = p;
-
-    pa_assert(profile);
-
-    pa_dbusiface_card_profile_free(profile);
-}
-
 void pa_dbusiface_card_free(pa_dbusiface_card *c) {
     pa_assert(c);
 
@@ -558,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, profile_free_cb, NULL);
+    pa_hashmap_free(c->profiles, (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 97a46a5..a9716bc 100644
--- a/src/modules/dbus/iface-core.c
+++ b/src/modules/dbus/iface-core.c
@@ -2089,54 +2089,6 @@ pa_dbusiface_core *pa_dbusiface_core_new(pa_core *core) {
     return c;
 }
 
-static void free_card_cb(void *p, void *userdata) {
-    pa_dbusiface_card *c = p;
-
-    pa_assert(c);
-
-    pa_dbusiface_card_free(c);
-}
-
-static void free_device_cb(void *p, void *userdata) {
-    pa_dbusiface_device *d = p;
-
-    pa_assert(d);
-
-    pa_dbusiface_device_free(d);
-}
-
-static void free_stream_cb(void *p, void *userdata) {
-    pa_dbusiface_stream *s = p;
-
-    pa_assert(s);
-
-    pa_dbusiface_stream_free(s);
-}
-
-static void free_sample_cb(void *p, void *userdata) {
-    pa_dbusiface_sample *s = p;
-
-    pa_assert(s);
-
-    pa_dbusiface_sample_free(s);
-}
-
-static void free_module_cb(void *p, void *userdata) {
-    pa_dbusiface_module *m = p;
-
-    pa_assert(m);
-
-    pa_dbusiface_module_free(m);
-}
-
-static void free_client_cb(void *p, void *userdata) {
-    pa_dbusiface_client *c = p;
-
-    pa_assert(c);
-
-    pa_dbusiface_client_free(c);
-}
-
 void pa_dbusiface_core_free(pa_dbusiface_core *c) {
     pa_assert(c);
 
@@ -2145,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, free_card_cb, NULL);
-    pa_hashmap_free(c->sinks_by_path, NULL, NULL);
-    pa_hashmap_free(c->sinks_by_index, free_device_cb, NULL);
-    pa_hashmap_free(c->sources_by_path, NULL, NULL);
-    pa_hashmap_free(c->sources_by_index, free_device_cb, NULL);
-    pa_hashmap_free(c->playback_streams, free_stream_cb, NULL);
-    pa_hashmap_free(c->record_streams, free_stream_cb, NULL);
-    pa_hashmap_free(c->samples, free_sample_cb, NULL);
-    pa_hashmap_free(c->modules, free_module_cb, NULL);
-    pa_hashmap_free(c->clients, free_client_cb, NULL);
+    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_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 151938d..888d407 100644
--- a/src/modules/dbus/iface-device.c
+++ b/src/modules/dbus/iface-device.c
@@ -1266,14 +1266,6 @@ pa_dbusiface_device *pa_dbusiface_device_new_source(pa_dbusiface_core *core, pa_
     return d;
 }
 
-static void port_free_cb(void *p, void *userdata) {
-    pa_dbusiface_device_port *port = p;
-
-    pa_assert(port);
-
-    pa_dbusiface_device_port_free(port);
-}
-
 void pa_dbusiface_device_free(pa_dbusiface_device *d) {
     pa_assert(d);
 
@@ -1287,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, port_free_cb, NULL);
+    pa_hashmap_free(d->ports, (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 5304116..c60d0f0 100644
--- a/src/modules/gconf/module-gconf.c
+++ b/src/modules/gconf/module-gconf.c
@@ -200,7 +200,7 @@ static void load_module(
     m->items[i].index = mod->index;
 }
 
-static void module_info_free(void *p, void *userdata) {
+static void module_info_free(void *p) {
     struct module_info *m = p;
 
     pa_assert(m);
@@ -291,7 +291,7 @@ static int handle_event(struct userdata *u) {
 
                 if ((m = pa_hashmap_get(u->module_infos, name))) {
                     pa_hashmap_remove(u->module_infos, name);
-                    module_info_free(m, u);
+                    module_info_free(m);
                 }
 
                 pa_xfree(name);
@@ -401,7 +401,7 @@ void pa__done(pa_module*m) {
         pa_close(u->fd);
 
     if (u->module_infos)
-        pa_hashmap_free(u->module_infos, module_info_free, NULL);
+        pa_hashmap_free(u->module_infos, (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 667b6b7..d29d518 100644
--- a/src/modules/macosx/module-bonjour-publish.c
+++ b/src/modules/macosx/module-bonjour-publish.c
@@ -490,7 +490,7 @@ void pa__done(pa_module*m) {
     unpublish_all_services(u);
 
     if (u->services)
-        pa_hashmap_free(u->services, NULL, NULL);
+        pa_hashmap_free(u->services, 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 6bba2b3..ee3b54c 100644
--- a/src/modules/module-augment-properties.c
+++ b/src/modules/module-augment-properties.c
@@ -347,14 +347,8 @@ void pa__done(pa_module *m) {
     if (u->client_proplist_changed_slot)
         pa_hook_slot_free(u->client_proplist_changed_slot);
 
-    if (u->cache) {
-        struct rule *r;
-
-        while ((r = pa_hashmap_steal_first(u->cache)))
-            rule_free(r);
-
-        pa_hashmap_free(u->cache, NULL, NULL);
-    }
+    if (u->cache)
+        pa_hashmap_free(u->cache, (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 51923fd..3b061b6 100644
--- a/src/modules/module-card-restore.c
+++ b/src/modules/module-card-restore.c
@@ -136,7 +136,7 @@ static void port_info_update(struct port_info *p_info, pa_device_port *port) {
     p_info->offset = port->latency_offset;
 }
 
-static void port_info_free(struct port_info *p_info, void *userdata) {
+static void port_info_free(struct port_info *p_info) {
     pa_assert(p_info);
 
     pa_xfree(p_info->name);
@@ -147,7 +147,7 @@ static void entry_free(struct entry* e) {
     pa_assert(e);
 
     pa_xfree(e->profile);
-    pa_hashmap_free(e->ports, (pa_free2_cb_t) port_info_free, NULL);
+    pa_hashmap_free(e->ports, (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 29f7e66..c9c2f45 100644
--- a/src/modules/module-console-kit.c
+++ b/src/modules/module-console-kit.c
@@ -347,19 +347,14 @@ fail:
 
 void pa__done(pa_module *m) {
     struct userdata *u;
-    struct session *session;
 
     pa_assert(m);
 
     if (!(u = m->userdata))
         return;
 
-    if (u->sessions) {
-        while ((session = pa_hashmap_steal_first(u->sessions)))
-            free_session(session);
-
-        pa_hashmap_free(u->sessions, NULL, NULL);
-    }
+    if (u->sessions)
+        pa_hashmap_free(u->sessions, (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 12eddec..1207824 100644
--- a/src/modules/module-device-manager.c
+++ b/src/modules/module-device-manager.c
@@ -1302,7 +1302,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                     pa_xfree(device);
                 }
 
-                pa_hashmap_free(h, NULL, NULL);
+                pa_hashmap_free(h, NULL);
                 pa_log_error("Protocol error on reorder");
                 goto fail;
             }
@@ -1314,7 +1314,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                     pa_xfree(device);
                 }
 
-                pa_hashmap_free(h, NULL, NULL);
+                pa_hashmap_free(h, NULL);
                 pa_log_error("Client specified an unknown device in it's reorder list.");
                 goto fail;
             }
@@ -1329,7 +1329,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
                     pa_xfree(device);
                 }
 
-                pa_hashmap_free(h, NULL, NULL);
+                pa_hashmap_free(h, NULL);
                 pa_log_error("Attempted to reorder mixed devices (sinks and sources)");
                 goto fail;
             }
@@ -1402,7 +1402,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
         while ((device = pa_hashmap_steal_first(h))) {
             devices[idx++] = device;
         }
-        pa_hashmap_free(h, NULL, NULL);
+        pa_hashmap_free(h, 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 cd0cd8d..6826a0a 100644
--- a/src/modules/module-filter-apply.c
+++ b/src/modules/module-filter-apply.c
@@ -743,7 +743,7 @@ void pa__done(pa_module *m) {
             filter_free(f);
         }
 
-        pa_hashmap_free(u->filters, NULL, NULL);
+        pa_hashmap_free(u->filters, NULL);
     }
 
     pa_xfree(u);
diff --git a/src/modules/module-role-cork.c b/src/modules/module-role-cork.c
index 8f8b58d..77bac1e 100644
--- a/src/modules/module-role-cork.c
+++ b/src/modules/module-role-cork.c
@@ -311,7 +311,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, NULL);
+        pa_hashmap_free(u->cork_state, NULL);
 
     pa_xfree(u);
 
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 1166a63..64bb241 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -2491,16 +2491,6 @@ fail:
     return -1;
 }
 
-#ifdef HAVE_DBUS
-static void free_dbus_entry_cb(void *p, void *userdata) {
-    struct dbus_entry *de = p;
-
-    pa_assert(de);
-
-    dbus_entry_free(de);
-}
-#endif
-
 void pa__done(pa_module*m) {
     struct userdata* u;
 
@@ -2516,7 +2506,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, free_dbus_entry_cb, NULL);
+        pa_hashmap_free(u->dbus_entries, (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 f27dafd..02a6b91 100644
--- a/src/modules/module-suspend-on-idle.c
+++ b/src/modules/module-suspend-on-idle.c
@@ -474,7 +474,6 @@ fail:
 
 void pa__done(pa_module*m) {
     struct userdata *u;
-    struct device_info *d;
 
     pa_assert(m);
 
@@ -519,10 +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);
 
-    while ((d = pa_hashmap_steal_first(u->device_infos)))
-        device_info_free(d);
-
-    pa_hashmap_free(u->device_infos, NULL, NULL);
+    pa_hashmap_free(u->device_infos, (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 024c1eb..2f24711 100644
--- a/src/modules/module-systemd-login.c
+++ b/src/modules/module-systemd-login.c
@@ -222,15 +222,8 @@ void pa__done(pa_module *m) {
         return;
 
     if (u->sessions) {
-        while ((session = pa_hashmap_steal_first(u->sessions)))
-            free_session(session);
-
-        pa_hashmap_free(u->sessions, NULL, NULL);
-
-        while ((session = pa_hashmap_steal_first(u->previous_sessions)))
-            free_session(session);
-
-        pa_hashmap_free(u->previous_sessions, NULL, NULL);
+        pa_hashmap_free(u->sessions, (pa_free_cb_t) free_session);
+        pa_hashmap_free(u->previous_sessions, (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 185c179..76cab90 100644
--- a/src/modules/module-udev-detect.c
+++ b/src/modules/module-udev-detect.c
@@ -817,14 +817,8 @@ void pa__done(pa_module *m) {
     if (u->inotify_fd >= 0)
         pa_close(u->inotify_fd);
 
-    if (u->devices) {
-        struct device *d;
-
-        while ((d = pa_hashmap_steal_first(u->devices)))
-            device_free(d);
-
-        pa_hashmap_free(u->devices, NULL, NULL);
-    }
+    if (u->devices)
+        pa_hashmap_free(u->devices, (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 b17f6e5..4887510 100644
--- a/src/modules/module-zeroconf-discover.c
+++ b/src/modules/module-zeroconf-discover.c
@@ -426,7 +426,7 @@ void pa__done(pa_module*m) {
             tunnel_free(t);
         }
 
-        pa_hashmap_free(u->tunnels, NULL, NULL);
+        pa_hashmap_free(u->tunnels, NULL);
     }
 
     pa_xfree(u);
diff --git a/src/modules/module-zeroconf-publish.c b/src/modules/module-zeroconf-publish.c
index 0c20cf6..c21ff3e 100644
--- a/src/modules/module-zeroconf-publish.c
+++ b/src/modules/module-zeroconf-publish.c
@@ -326,8 +326,10 @@ static int publish_service(struct service *s) {
 finish:
 
     /* Remove this service */
-    if (r < 0)
+    if (r < 0) {
+        pa_hashmap_remove(s->userdata->services, s->device);
         service_free(s);
+    }
 
     avahi_string_list_free(txt);
 
@@ -374,8 +376,6 @@ 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);
-
     if (s->entry_group) {
         pa_log_debug("Removing entry group for %s.", s->service_name);
         avahi_entry_group_free(s->entry_group);
@@ -413,7 +413,7 @@ static pa_hook_result_t device_unlink_cb(pa_core *c, pa_object *o, struct userda
     pa_assert(c);
     pa_object_assert_ref(o);
 
-    if ((s = pa_hashmap_get(u->services, o)))
+    if ((s = pa_hashmap_remove(u->services, o)))
         service_free(s);
 
     return PA_HOOK_OK;
@@ -661,14 +661,8 @@ void pa__done(pa_module*m) {
     if (!(u = m->userdata))
         return;
 
-    if (u->services) {
-        struct service *s;
-
-        while ((s = pa_hashmap_first(u->services)))
-            service_free(s);
-
-        pa_hashmap_free(u->services, NULL, NULL);
-    }
+    if (u->services)
+        pa_hashmap_free(u->services, (pa_free_cb_t) service_free);
 
     if (u->sink_new_slot)
         pa_hook_slot_free(u->sink_new_slot);
diff --git a/src/modules/raop/module-raop-discover.c b/src/modules/raop/module-raop-discover.c
index 7499f63..3db2c0e 100644
--- a/src/modules/raop/module-raop-discover.c
+++ b/src/modules/raop/module-raop-discover.c
@@ -381,7 +381,7 @@ void pa__done(pa_module*m) {
             tunnel_free(t);
         }
 
-        pa_hashmap_free(u->tunnels, NULL, NULL);
+        pa_hashmap_free(u->tunnels, NULL);
     }
 
     pa_xfree(u);
diff --git a/src/modules/rtp/headerlist.c b/src/modules/rtp/headerlist.c
index 0fef835..3007518 100644
--- a/src/modules/rtp/headerlist.c
+++ b/src/modules/rtp/headerlist.c
@@ -56,12 +56,7 @@ pa_headerlist* pa_headerlist_new(void) {
 }
 
 void pa_headerlist_free(pa_headerlist* p) {
-    struct header *hdr;
-
-    while ((hdr = pa_hashmap_steal_first(MAKE_HASHMAP(p))))
-        header_free(hdr);
-
-    pa_hashmap_free(MAKE_HASHMAP(p), NULL, NULL);
+    pa_hashmap_free(MAKE_HASHMAP(p), (pa_free_cb_t) header_free);
 }
 
 int pa_headerlist_puts(pa_headerlist *p, const char *key, const char *value) {
diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c
index 3e9250c..45d03f5 100644
--- a/src/modules/rtp/module-rtp-recv.c
+++ b/src/modules/rtp/module-rtp-recv.c
@@ -186,6 +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);
     session_free(s);
 }
 
@@ -606,7 +607,6 @@ static void session_free(struct session *s) {
     PA_LLIST_REMOVE(struct session, s->userdata->sessions, s);
     pa_assert(s->userdata->n_sessions >= 1);
     s->userdata->n_sessions--;
-    pa_hashmap_remove(s->userdata->by_origin, s->sdp_info.origin);
 
     pa_memblockq_free(s->memblockq);
     pa_sdp_info_destroy(&s->sdp_info);
@@ -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_get(u->by_origin, info.origin)))
+        if ((s = pa_hashmap_remove(u->by_origin, info.origin)))
             session_free(s);
 
         pa_sdp_info_destroy(&info);
@@ -674,8 +674,10 @@ 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)
+        if (k + DEATH_TIMEOUT < now.tv_sec) {
+            pa_hashmap_remove(u->by_origin, s->sdp_info.origin);
             session_free(s);
+        }
     }
 
     /* Restart timer */
@@ -753,7 +755,6 @@ fail:
 
 void pa__done(pa_module*m) {
     struct userdata *u;
-    struct session *s;
 
     pa_assert(m);
 
@@ -768,12 +769,8 @@ void pa__done(pa_module*m) {
 
     pa_sap_context_destroy(&u->sap_context);
 
-    if (u->by_origin) {
-        while ((s = pa_hashmap_first(u->by_origin)))
-            session_free(s);
-
-        pa_hashmap_free(u->by_origin, NULL, NULL);
-    }
+    if (u->by_origin)
+        pa_hashmap_free(u->by_origin, (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 4618635..7176412 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, NULL);
+        pa_hashmap_free(c->record_streams, NULL);
     if (c->playback_streams)
-        pa_hashmap_free(c->playback_streams, NULL, NULL);
+        pa_hashmap_free(c->playback_streams, NULL);
 
     if (c->mempool)
         pa_mempool_free(c->mempool);
diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c
index 2c197bc..33b150c 100644
--- a/src/pulse/proplist.c
+++ b/src/pulse/proplist.c
@@ -70,8 +70,7 @@ pa_proplist* pa_proplist_new(void) {
 void pa_proplist_free(pa_proplist* p) {
     pa_assert(p);
 
-    pa_proplist_clear(p);
-    pa_hashmap_free(MAKE_HASHMAP(p), NULL, NULL);
+    pa_hashmap_free(MAKE_HASHMAP(p), (pa_free_cb_t) property_free);
 }
 
 /** Will accept only valid UTF-8 */
diff --git a/src/pulsecore/card.c b/src/pulsecore/card.c
index afabc95..560e36e 100644
--- a/src/pulsecore/card.c
+++ b/src/pulsecore/card.c
@@ -57,7 +57,6 @@ pa_card_profile *pa_card_profile_new(const char *name, const char *description,
 
 void pa_card_profile_free(pa_card_profile *c) {
     pa_assert(c);
-    pa_assert(!c->card); /* Card profiles shouldn't be freed before removing them from the card. */
 
     pa_xfree(c->name);
     pa_xfree(c->description);
@@ -126,14 +125,8 @@ void pa_card_new_data_done(pa_card_new_data *data) {
 
     pa_proplist_free(data->proplist);
 
-    if (data->profiles) {
-        pa_card_profile *c;
-
-        while ((c = pa_hashmap_steal_first(data->profiles)))
-            pa_card_profile_free(c);
-
-        pa_hashmap_free(data->profiles, NULL, NULL);
-    }
+    if (data->profiles)
+        pa_hashmap_free(data->profiles, (pa_free_cb_t) pa_card_profile_free);
 
     if (data->ports)
         pa_device_port_hashmap_free(data->ports);
@@ -246,16 +239,8 @@ void pa_card_free(pa_card *c) {
 
     pa_device_port_hashmap_free(c->ports);
 
-    if (c->profiles) {
-        pa_card_profile *p;
-
-        while ((p = pa_hashmap_steal_first(c->profiles))) {
-            p->card = NULL;
-            pa_card_profile_free(p);
-        }
-
-        pa_hashmap_free(c->profiles, NULL, NULL);
-    }
+    if (c->profiles)
+        pa_hashmap_free(c->profiles, (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 e4f9140..37f3fae 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, NULL);
 
     pa_assert(pa_hashmap_isempty(c->namereg));
-    pa_hashmap_free(c->namereg, NULL, NULL);
+    pa_hashmap_free(c->namereg, NULL);
 
     pa_assert(pa_hashmap_isempty(c->shared));
-    pa_hashmap_free(c->shared, NULL, NULL);
+    pa_hashmap_free(c->shared, NULL);
 
     pa_subscription_free_all(c);
 
diff --git a/src/pulsecore/database-simple.c b/src/pulsecore/database-simple.c
index db68158..5dd3ac9 100644
--- a/src/pulsecore/database-simple.c
+++ b/src/pulsecore/database-simple.c
@@ -264,10 +264,9 @@ void pa_database_close(pa_database *database) {
     pa_assert(db);
 
     pa_database_sync(database);
-    pa_database_clear(database);
     pa_xfree(db->filename);
     pa_xfree(db->tmp_filename);
-    pa_hashmap_free(db->map, NULL, NULL);
+    pa_hashmap_free(db->map, (pa_free_cb_t) free_entry);
     pa_xfree(db);
 }
 
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 6d787ac..5c7a5bb 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -56,8 +56,10 @@ static void device_port_free(pa_object *o) {
 
     if (p->proplist)
         pa_proplist_free(p->proplist);
+
     if (p->profiles)
-        pa_hashmap_free(p->profiles, NULL, NULL);
+        pa_hashmap_free(p->profiles, NULL);
+
     pa_xfree(p->name);
     pa_xfree(p->description);
     pa_xfree(p);
@@ -88,14 +90,9 @@ pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *des
 }
 
 void pa_device_port_hashmap_free(pa_hashmap *h) {
-    pa_device_port *p;
-
     pa_assert(h);
 
-    while ((p = pa_hashmap_steal_first(h)))
-        pa_device_port_unref(p);
-
-    pa_hashmap_free(h, NULL, NULL);
+    pa_hashmap_free(h, (pa_free_cb_t) pa_device_port_unref);
 }
 
 void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) {
diff --git a/src/pulsecore/hashmap.c b/src/pulsecore/hashmap.c
index e368512..cfd08b7 100644
--- a/src/pulsecore/hashmap.c
+++ b/src/pulsecore/hashmap.c
@@ -101,7 +101,7 @@ static void remove_entry(pa_hashmap *h, struct hashmap_entry *e) {
     h->n_entries--;
 }
 
-void pa_hashmap_free(pa_hashmap*h, pa_free2_cb_t free_cb, void *userdata) {
+void pa_hashmap_free(pa_hashmap *h, pa_free_cb_t free_cb) {
     pa_assert(h);
 
     while (h->iterate_list_head) {
@@ -110,7 +110,7 @@ void pa_hashmap_free(pa_hashmap*h, pa_free2_cb_t free_cb, void *userdata) {
         remove_entry(h, h->iterate_list_head);
 
         if (free_cb)
-            free_cb(data, userdata);
+            free_cb(data);
     }
 
     pa_xfree(h);
diff --git a/src/pulsecore/hashmap.h b/src/pulsecore/hashmap.h
index ac2092a..8d892b8 100644
--- a/src/pulsecore/hashmap.h
+++ b/src/pulsecore/hashmap.h
@@ -22,6 +22,8 @@
   USA.
 ***/
 
+#include <pulse/def.h>
+
 #include <pulsecore/idxset.h>
 
 /* Simple Implementation of a hash table. Memory management is the
@@ -35,7 +37,7 @@ typedef struct pa_hashmap pa_hashmap;
 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_free2_cb_t free_cb, void *userdata);
+void pa_hashmap_free(pa_hashmap*, pa_free_cb_t free_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);
diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c
index ea7b274..5b77df3 100644
--- a/src/pulsecore/memblock.c
+++ b/src/pulsecore/memblock.c
@@ -964,8 +964,8 @@ void pa_memimport_free(pa_memimport *i) {
 
     pa_mutex_unlock(i->pool->mutex);
 
-    pa_hashmap_free(i->blocks, NULL, NULL);
-    pa_hashmap_free(i->segments, NULL, NULL);
+    pa_hashmap_free(i->blocks, NULL);
+    pa_hashmap_free(i->segments, NULL);
 
     pa_mutex_free(i->mutex);
 
diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c
index 0abc243..d48a2c8 100644
--- a/src/pulsecore/modargs.c
+++ b/src/pulsecore/modargs.c
@@ -247,7 +247,7 @@ fail:
     return NULL;
 }
 
-static void free_func(void *p, void*userdata) {
+static void free_func(void *p) {
     struct entry *e = p;
     pa_assert(e);
 
@@ -259,8 +259,8 @@ static void free_func(void *p, void*userdata) {
 void pa_modargs_free(pa_modargs*ma) {
     pa_assert(ma);
 
-    pa_hashmap_free(ma->raw, free_func, NULL);
-    pa_hashmap_free(ma->unescaped, free_func, NULL);
+    pa_hashmap_free(ma->raw, free_func);
+    pa_hashmap_free(ma->unescaped, free_func);
     pa_xfree(ma);
 }
 
diff --git a/src/pulsecore/mutex-win32.c b/src/pulsecore/mutex-win32.c
index f4652a9..e70f230 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, NULL);
+    pa_hashmap_free(c->wait_events, NULL);
     pa_xfree(c);
 }
 
diff --git a/src/pulsecore/protocol-dbus.c b/src/pulsecore/protocol-dbus.c
index c82ea4a..dab4678 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, NULL);
-    pa_hashmap_free(p->connections, NULL, NULL);
+    pa_hashmap_free(p->objects, NULL);
+    pa_hashmap_free(p->connections, NULL);
     pa_idxset_free(p->extensions, NULL, NULL);
 
     for (i = 0; i < PA_DBUS_PROTOCOL_HOOK_MAX; ++i)
@@ -789,8 +789,7 @@ static void unregister_object(pa_dbus_protocol *p, struct object_entry *obj_entr
         pa_assert_se(dbus_connection_unregister_object_path(conn_entry->connection, obj_entry->path));
 }
 
-static void method_handler_free_cb(void *p, void *userdata) {
-    pa_dbus_method_handler *h = p;
+static void method_handler_free(pa_dbus_method_handler *h) {
     unsigned i;
 
     pa_assert(h);
@@ -807,15 +806,7 @@ static void method_handler_free_cb(void *p, void *userdata) {
     pa_xfree(h);
 }
 
-static void method_signature_free_cb(void *p, void *userdata) {
-    pa_assert(p);
-
-    pa_xfree(p);
-}
-
-static void property_handler_free_cb(void *p, void *userdata) {
-    pa_dbus_property_handler *h = p;
-
+static void property_handler_free(pa_dbus_property_handler *h) {
     pa_assert(h);
 
     pa_xfree((char *) h->property_name);
@@ -844,9 +835,9 @@ int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, con
     pa_log_debug("Interface %s removed from object %s", iface_entry->name, obj_entry->path);
 
     pa_xfree(iface_entry->name);
-    pa_hashmap_free(iface_entry->method_signatures, method_signature_free_cb, NULL);
-    pa_hashmap_free(iface_entry->method_handlers, method_handler_free_cb, NULL);
-    pa_hashmap_free(iface_entry->property_handlers, property_handler_free_cb, NULL);
+    pa_hashmap_free(iface_entry->method_signatures, pa_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);
 
     for (i = 0; i < iface_entry->n_signals; ++i) {
         unsigned j;
@@ -870,7 +861,7 @@ int pa_dbus_protocol_remove_interface(pa_dbus_protocol *p, const char* path, con
 
         pa_hashmap_remove(p->objects, path);
         pa_xfree(obj_entry->path);
-        pa_hashmap_free(obj_entry->interfaces, NULL, NULL);
+        pa_hashmap_free(obj_entry->interfaces, NULL);
         pa_xfree(obj_entry->introspection);
         pa_xfree(obj_entry);
     }
@@ -952,7 +943,6 @@ static void signal_paths_entry_free(struct signal_paths_entry *e) {
 
 int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *conn) {
     struct connection_entry *conn_entry = NULL;
-    struct signal_paths_entry *signal_paths_entry = NULL;
     char *object_path = NULL;
 
     pa_assert(p);
@@ -970,10 +960,7 @@ int pa_dbus_protocol_unregister_connection(pa_dbus_protocol *p, DBusConnection *
 
     pa_idxset_free(conn_entry->all_signals_objects, NULL, NULL);
 
-    while ((signal_paths_entry = pa_hashmap_steal_first(conn_entry->listening_signals)))
-        signal_paths_entry_free(signal_paths_entry);
-
-    pa_hashmap_free(conn_entry->listening_signals, NULL, NULL);
+    pa_hashmap_free(conn_entry->listening_signals, (pa_free_cb_t) signal_paths_entry_free);
     pa_xfree(conn_entry);
 
     return 0;
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 88808bf..6a9379e 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -5100,7 +5100,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, NULL);
+    pa_hashmap_free(p->extensions, NULL);
 
     pa_assert_se(pa_shared_remove(p->core, "native-protocol") >= 0);
 
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index a6ddb15..165faa7 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -74,10 +74,6 @@ static void volume_factor_entry_free(struct volume_factor_entry *volume_entry) {
     pa_xfree(volume_entry);
 }
 
-static void volume_factor_entry_free2(struct volume_factor_entry *volume_entry, void *userdarta) {
-    volume_factor_entry_free(volume_entry);
-}
-
 static void volume_factor_from_hashmap(pa_cvolume *v, pa_hashmap *items, uint8_t channels) {
     struct volume_factor_entry *entry;
     void *state = NULL;
@@ -245,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_free2_cb_t) volume_factor_entry_free2, NULL);
+        pa_hashmap_free(data->volume_factor_items, (pa_free_cb_t) volume_factor_entry_free);
 
     if (data->volume_factor_sink_items)
-        pa_hashmap_free(data->volume_factor_sink_items, (pa_free2_cb_t) volume_factor_entry_free2, NULL);
+        pa_hashmap_free(data->volume_factor_sink_items, (pa_free_cb_t) volume_factor_entry_free);
 
     pa_proplist_free(data->proplist);
 }
@@ -745,12 +741,13 @@ static void sink_input_free(pa_object *o) {
         pa_idxset_free(i->direct_outputs, NULL, NULL);
 
     if (i->thread_info.direct_outputs)
-        pa_hashmap_free(i->thread_info.direct_outputs, NULL, NULL);
+        pa_hashmap_free(i->thread_info.direct_outputs, NULL);
 
     if (i->volume_factor_items)
-        pa_hashmap_free(i->volume_factor_items, (pa_free2_cb_t) volume_factor_entry_free2, NULL);
+        pa_hashmap_free(i->volume_factor_items, (pa_free_cb_t) volume_factor_entry_free);
+
     if (i->volume_factor_sink_items)
-        pa_hashmap_free(i->volume_factor_sink_items, (pa_free2_cb_t) volume_factor_entry_free2, NULL);
+        pa_hashmap_free(i->volume_factor_sink_items, (pa_free_cb_t) volume_factor_entry_free);
 
     pa_xfree(i->driver);
     pa_xfree(i);
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 175cfe5..171072e 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -715,7 +715,6 @@ void pa_sink_unlink(pa_sink* s) {
 /* Called from main context */
 static void sink_free(pa_object *o) {
     pa_sink *s = PA_SINK(o);
-    pa_sink_input *i;
 
     pa_assert(s);
     pa_assert_ctl_context();
@@ -732,11 +731,7 @@ static void sink_free(pa_object *o) {
     }
 
     pa_idxset_free(s->inputs, NULL, NULL);
-
-    while ((i = pa_hashmap_steal_first(s->thread_info.inputs)))
-        pa_sink_input_unref(i);
-
-    pa_hashmap_free(s->thread_info.inputs, NULL, NULL);
+    pa_hashmap_free(s->thread_info.inputs, (pa_free_cb_t) pa_sink_input_unref);
 
     if (s->silence.memblock)
         pa_memblock_unref(s->silence.memblock);
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index f336119..5c12137 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -648,7 +648,6 @@ void pa_source_unlink(pa_source *s) {
 
 /* Called from main context */
 static void source_free(pa_object *o) {
-    pa_source_output *so;
     pa_source *s = PA_SOURCE(o);
 
     pa_assert(s);
@@ -661,11 +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, NULL);
-
-    while ((so = pa_hashmap_steal_first(s->thread_info.outputs)))
-        pa_source_output_unref(so);
-
-    pa_hashmap_free(s->thread_info.outputs, NULL, NULL);
+    pa_hashmap_free(s->thread_info.outputs, (pa_free_cb_t) pa_source_output_unref);
 
     if (s->silence.memblock)
         pa_memblock_unref(s->silence.memblock);

commit dcf043842e6bef0680bb246e7266b7c0829d34d4
Author: Tanu Kaskinen <tanuk at iki.fi>
Date:   Tue Feb 12 21:36:52 2013 +0200

    gconf: Remove needless userdata function arguments

diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c
index e517d52..5304116 100644
--- a/src/modules/gconf/module-gconf.c
+++ b/src/modules/gconf/module-gconf.c
@@ -131,11 +131,14 @@ static char *read_string(struct userdata *u) {
     }
 }
 
-static void unload_one_module(struct userdata *u, struct module_info*m, unsigned i) {
-    pa_assert(u);
+static void unload_one_module(struct module_info *m, unsigned i) {
+    struct userdata *u;
+
     pa_assert(m);
     pa_assert(i < m->n_items);
 
+    u = m->userdata;
+
     if (m->items[i].index == PA_INVALID_INDEX)
         return;
 
@@ -147,40 +150,40 @@ static void unload_one_module(struct userdata *u, struct module_info*m, unsigned
     m->items[i].name = m->items[i].args = NULL;
 }
 
-static void unload_all_modules(struct userdata *u, struct module_info*m) {
+static void unload_all_modules(struct module_info *m) {
     unsigned i;
 
-    pa_assert(u);
     pa_assert(m);
 
     for (i = 0; i < m->n_items; i++)
-        unload_one_module(u, m, i);
+        unload_one_module(m, i);
 
     m->n_items = 0;
 }
 
 static void load_module(
-        struct userdata *u,
         struct module_info *m,
         unsigned i,
         const char *name,
         const char *args,
         pa_bool_t is_new) {
 
+    struct userdata *u;
     pa_module *mod;
 
-    pa_assert(u);
     pa_assert(m);
     pa_assert(name);
     pa_assert(args);
 
+    u = m->userdata;
+
     if (!is_new) {
         if (m->items[i].index != PA_INVALID_INDEX &&
             pa_streq(m->items[i].name, name) &&
             pa_streq(m->items[i].args, args))
             return;
 
-        unload_one_module(u, m, i);
+        unload_one_module(m, i);
     }
 
     pa_log_debug("Loading module '%s' with args '%s' due to GConf configuration.", name, args);
@@ -199,12 +202,10 @@ static void load_module(
 
 static void module_info_free(void *p, void *userdata) {
     struct module_info *m = p;
-    struct userdata *u = userdata;
 
     pa_assert(m);
-    pa_assert(u);
 
-    unload_all_modules(u, m);
+    unload_all_modules(m);
     pa_xfree(m->name);
     pa_xfree(m);
 }
@@ -264,7 +265,7 @@ static int handle_event(struct userdata *u) {
                         goto fail;
                     }
 
-                    load_module(u, m, i, module, args, i >= m->n_items);
+                    load_module(m, i, module, args, i >= m->n_items);
 
                     i++;
 
@@ -274,7 +275,7 @@ static int handle_event(struct userdata *u) {
 
                 /* Unload all removed modules */
                 for (j = i; j < m->n_items; j++)
-                    unload_one_module(u, m, j);
+                    unload_one_module(m, j);
 
                 m->n_items = i;
 
@@ -400,7 +401,7 @@ void pa__done(pa_module*m) {
         pa_close(u->fd);
 
     if (u->module_infos)
-        pa_hashmap_free(u->module_infos, module_info_free, u);
+        pa_hashmap_free(u->module_infos, module_info_free, NULL);
 
     pa_xfree(u);
 }

commit cfb895438a740132d4b67f155719c7a0f3da8aaa
Author: Tanu Kaskinen <tanuk at iki.fi>
Date:   Tue Feb 12 21:36:51 2013 +0200

    gconf: Add userdata pointer to struct module_info
    
    This will be useful in simplifying function argument lists.

diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c
index c951d90..e517d52 100644
--- a/src/modules/gconf/module-gconf.c
+++ b/src/modules/gconf/module-gconf.c
@@ -50,6 +50,8 @@ PA_MODULE_LOAD_ONCE(TRUE);
 #define MAX_MODULES 10
 #define BUF_MAX 2048
 
+struct userdata;
+
 struct module_item {
     char *name;
     char *args;
@@ -57,6 +59,7 @@ struct module_item {
 };
 
 struct module_info {
+    struct userdata *userdata;
     char *name;
 
     struct module_item items[MAX_MODULES];
@@ -233,6 +236,7 @@ static int handle_event(struct userdata *u) {
 
                 if (!(m = pa_hashmap_get(u->module_infos, name))) {
                     m = pa_xnew(struct module_info, 1);
+                    m->userdata = u;
                     m->name = name;
                     m->n_items = 0;
                     pa_hashmap_put(u->module_infos, m->name, m);



More information about the pulseaudio-commits mailing list