spa: only remove embedded source from data loop from within the loop

Use `spa_loop_invoke()` to invoke a callback on the data loop
to remove an embedded `spa_source` from the data loop.

Embedded `spa_source` objects cannot be safely removed
while the loop is polling without risking potential
use-after-frees.
This commit is contained in:
Barnabás Pőcze 2022-03-04 16:51:31 +01:00 committed by Wim Taymans
parent 7647ea7c83
commit 60b9d9081b
7 changed files with 56 additions and 7 deletions

View file

@ -984,6 +984,13 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
return 0;
}
static int do_remove_timer(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct impl *this = user_data;
spa_loop_remove_source(this->data_loop, &this->timer_source);
return 0;
}
static int impl_clear(struct spa_handle *handle)
{
struct impl *this;
@ -993,7 +1000,7 @@ static int impl_clear(struct spa_handle *handle)
this = (struct impl *) handle;
if (this->data_loop)
spa_loop_remove_source(this->data_loop, &this->timer_source);
spa_loop_invoke(this->data_loop, do_remove_timer, 0, NULL, 0, true, this);
spa_system_close(this->data_system, this->timer_source.fd);
return 0;

View file

@ -350,6 +350,13 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
return 0;
}
static int do_remove_timer(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct impl *this = user_data;
spa_loop_remove_source(this->data_loop, &this->timer_source);
return 0;
}
static int impl_clear(struct spa_handle *handle)
{
struct impl *this;
@ -358,7 +365,7 @@ static int impl_clear(struct spa_handle *handle)
this = (struct impl *) handle;
spa_loop_remove_source(this->data_loop, &this->timer_source);
spa_loop_invoke(this->data_loop, do_remove_timer, 0, NULL, 0, true, this);
spa_system_close(this->data_system, this->timer_source.fd);
return 0;

View file

@ -779,6 +779,13 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
return 0;
}
static int do_remove_timer(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct impl *this = user_data;
spa_loop_remove_source(this->data_loop, &this->timer_source);
return 0;
}
static int impl_clear(struct spa_handle *handle)
{
struct impl *this;
@ -787,7 +794,7 @@ static int impl_clear(struct spa_handle *handle)
this = (struct impl *) handle;
spa_loop_remove_source(this->data_loop, &this->timer_source);
spa_loop_invoke(this->data_loop, do_remove_timer, 0, NULL, 0, true, this);
spa_system_close(this->data_system, this->timer_source.fd);
return 0;

View file

@ -698,6 +698,13 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
return 0;
}
static int do_remove_timer(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct impl *this = user_data;
spa_loop_remove_source(this->data_loop, &this->timer_source);
return 0;
}
static int impl_clear(struct spa_handle *handle)
{
struct impl *this;
@ -707,7 +714,7 @@ static int impl_clear(struct spa_handle *handle)
this = (struct impl *) handle;
if (this->data_loop)
spa_loop_remove_source(this->data_loop, &this->timer_source);
spa_loop_invoke(this->data_loop, do_remove_timer, 0, NULL, 0, true, this);
spa_system_close(this->data_system, this->timer_source.fd);
return 0;

View file

@ -731,6 +731,13 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
return 0;
}
static int do_remove_timer(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct impl *this = user_data;
spa_loop_remove_source(this->data_loop, &this->timer_source);
return 0;
}
static int impl_clear(struct spa_handle *handle)
{
struct impl *this;
@ -740,7 +747,7 @@ static int impl_clear(struct spa_handle *handle)
this = (struct impl *) handle;
if (this->data_loop)
spa_loop_remove_source(this->data_loop, &this->timer_source);
spa_loop_invoke(this->data_loop, do_remove_timer, 0, NULL, 0, true, this);
spa_system_close(this->data_system, this->timer_source.fd);
return 0;

View file

@ -838,6 +838,13 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
return 0;
}
static int do_remove_timer(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct impl *this = user_data;
spa_loop_remove_source(this->data_loop, &this->timer_source);
return 0;
}
static int impl_clear(struct spa_handle *handle)
{
struct impl *this;
@ -847,7 +854,7 @@ static int impl_clear(struct spa_handle *handle)
this = (struct impl *) handle;
if (this->data_loop)
spa_loop_remove_source(this->data_loop, &this->timer_source);
spa_loop_invoke(this->data_loop, do_remove_timer, 0, NULL, 0, true, this);
spa_system_close(this->data_system, this->timer_source.fd);
return 0;

View file

@ -854,6 +854,13 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
return 0;
}
static int do_remove_timer(struct spa_loop *loop, bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct impl *this = user_data;
spa_loop_remove_source(this->data_loop, &this->timer_source);
return 0;
}
static int impl_clear(struct spa_handle *handle)
{
struct impl *this;
@ -863,7 +870,7 @@ static int impl_clear(struct spa_handle *handle)
this = (struct impl *) handle;
if (this->data_loop)
spa_loop_remove_source(this->data_loop, &this->timer_source);
spa_loop_invoke(this->data_loop, do_remove_timer, 0, NULL, 0, true, this);
spa_system_close(this->data_system, this->timer_source.fd);
return 0;