mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
media-session: free sm_objects only after session destroy emitted
Allows monitors (eg. bluez5) free any sm_objects they hold in session_destroy. In session_shutdown, destroy such objects before the event, and free them only afterward. Fixes double-free in bluez monitor.
This commit is contained in:
parent
6c94dc30a2
commit
d143c169cc
1 changed files with 22 additions and 2 deletions
|
|
@ -2184,12 +2184,27 @@ static void session_shutdown(struct impl *impl)
|
||||||
{
|
{
|
||||||
struct sm_object *obj;
|
struct sm_object *obj;
|
||||||
struct registry_event *re;
|
struct registry_event *re;
|
||||||
|
struct spa_list free_list;
|
||||||
|
|
||||||
pw_log_info(NAME" %p", impl);
|
pw_log_info(NAME" %p", impl);
|
||||||
sm_media_session_emit_shutdown(impl);
|
sm_media_session_emit_shutdown(impl);
|
||||||
|
|
||||||
spa_list_consume(obj, &impl->object_list, link)
|
/*
|
||||||
sm_object_destroy(obj);
|
* Monitors may still hold references to objects, which they
|
||||||
|
* drop in session destroy event, so don't free undiscarded
|
||||||
|
* objects yet. Destroy event handlers may remove any objects
|
||||||
|
* in the list, so iterate carefully.
|
||||||
|
*/
|
||||||
|
spa_list_init(&free_list);
|
||||||
|
spa_list_consume(obj, &impl->object_list, link) {
|
||||||
|
if (obj->destroyed) {
|
||||||
|
spa_list_remove(&obj->link);
|
||||||
|
spa_list_append(&free_list, &obj->link);
|
||||||
|
} else {
|
||||||
|
sm_object_destroy_maybe_free(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
spa_list_consume(re, &impl->registry_event_list, link)
|
spa_list_consume(re, &impl->registry_event_list, link)
|
||||||
registry_event_free(re);
|
registry_event_free(re);
|
||||||
|
|
||||||
|
|
@ -2197,6 +2212,11 @@ static void session_shutdown(struct impl *impl)
|
||||||
|
|
||||||
sm_media_session_emit_destroy(impl);
|
sm_media_session_emit_destroy(impl);
|
||||||
|
|
||||||
|
spa_list_consume(obj, &free_list, link)
|
||||||
|
sm_object_destroy(obj);
|
||||||
|
spa_list_consume(obj, &impl->object_list, link)
|
||||||
|
sm_object_destroy(obj); /* in case emit_destroy created new objects */
|
||||||
|
|
||||||
if (impl->registry) {
|
if (impl->registry) {
|
||||||
spa_hook_remove(&impl->registry_listener);
|
spa_hook_remove(&impl->registry_listener);
|
||||||
pw_proxy_destroy((struct pw_proxy*)impl->registry);
|
pw_proxy_destroy((struct pw_proxy*)impl->registry);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue