mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
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:
parent
7647ea7c83
commit
60b9d9081b
7 changed files with 56 additions and 7 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue