mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
bluez5: setting this->transport = NULL should block data thread
Since the data thread accesses the spa_bt_transport, its destroy event needs to sync with data thread to avoid races. Also check transport is present in places that need it.
This commit is contained in:
parent
a5e52c07b1
commit
da2fa8a599
4 changed files with 61 additions and 4 deletions
|
|
@ -596,6 +596,9 @@ static void a2dp_on_timeout(struct spa_source *source)
|
|||
struct spa_io_buffers *io = port->io;
|
||||
uint64_t prev_time, now_time;
|
||||
|
||||
if (this->transport == NULL)
|
||||
return;
|
||||
|
||||
if (this->started && spa_system_timerfd_read(this->data_system, this->timerfd, &exp) < 0)
|
||||
spa_log_warn(this->log, "error reading timerfd: %s", strerror(errno));
|
||||
|
||||
|
|
@ -1221,11 +1224,23 @@ static const struct spa_node_methods impl_node = {
|
|||
.process = impl_node_process,
|
||||
};
|
||||
|
||||
static int do_transport_destroy(struct spa_loop *loop,
|
||||
bool async,
|
||||
uint32_t seq,
|
||||
const void *data,
|
||||
size_t size,
|
||||
void *user_data)
|
||||
{
|
||||
struct impl *this = user_data;
|
||||
this->transport = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void transport_destroy(void *data)
|
||||
{
|
||||
struct impl *this = data;
|
||||
spa_log_debug(this->log, "transport %p destroy", this->transport);
|
||||
this->transport = NULL;
|
||||
spa_loop_invoke(this->data_loop, do_transport_destroy, 0, NULL, 0, true, this);
|
||||
}
|
||||
|
||||
static const struct spa_bt_transport_events transport_events = {
|
||||
|
|
|
|||
|
|
@ -1092,11 +1092,23 @@ static const struct spa_node_methods impl_node = {
|
|||
.process = impl_node_process,
|
||||
};
|
||||
|
||||
static int do_transport_destroy(struct spa_loop *loop,
|
||||
bool async,
|
||||
uint32_t seq,
|
||||
const void *data,
|
||||
size_t size,
|
||||
void *user_data)
|
||||
{
|
||||
struct impl *this = user_data;
|
||||
this->transport = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void transport_destroy(void *data)
|
||||
{
|
||||
struct impl *this = data;
|
||||
spa_log_debug(this->log, "transport %p destroy", this->transport);
|
||||
this->transport = NULL;
|
||||
spa_loop_invoke(this->data_loop, do_transport_destroy, 0, NULL, 0, true, this);
|
||||
}
|
||||
|
||||
static void transport_state_changed(void *data, enum spa_bt_transport_state old,
|
||||
|
|
|
|||
|
|
@ -315,6 +315,9 @@ static void flush_data(struct impl *this)
|
|||
uint32_t min_in_size;
|
||||
uint8_t *packet;
|
||||
|
||||
if (this->transport == NULL)
|
||||
return;
|
||||
|
||||
/* get buffer */
|
||||
if (!port->current_buffer) {
|
||||
spa_return_if_fail(!spa_list_is_empty(&port->ready));
|
||||
|
|
@ -445,6 +448,9 @@ static void sco_on_timeout(struct spa_source *source)
|
|||
struct port *port = &this->port;
|
||||
uint64_t exp;
|
||||
|
||||
if (this->transport == NULL)
|
||||
return;
|
||||
|
||||
/* Read the timerfd */
|
||||
if (this->started && spa_system_timerfd_read(this->data_system, this->timerfd, &exp) < 0)
|
||||
spa_log_warn(this->log, "error reading timerfd: %s", strerror(errno));
|
||||
|
|
@ -1049,11 +1055,23 @@ static const struct spa_node_methods impl_node = {
|
|||
.process = impl_node_process,
|
||||
};
|
||||
|
||||
static int do_transport_destroy(struct spa_loop *loop,
|
||||
bool async,
|
||||
uint32_t seq,
|
||||
const void *data,
|
||||
size_t size,
|
||||
void *user_data)
|
||||
{
|
||||
struct impl *this = user_data;
|
||||
this->transport = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void transport_destroy(void *data)
|
||||
{
|
||||
struct impl *this = data;
|
||||
spa_log_debug(this->log, "transport %p destroy", this->transport);
|
||||
this->transport = NULL;
|
||||
spa_loop_invoke(this->data_loop, do_transport_destroy, 0, NULL, 0, true, this);
|
||||
}
|
||||
|
||||
static const struct spa_bt_transport_events transport_events = {
|
||||
|
|
|
|||
|
|
@ -1068,11 +1068,23 @@ static const struct spa_node_methods impl_node = {
|
|||
.process = impl_node_process,
|
||||
};
|
||||
|
||||
static int do_transport_destroy(struct spa_loop *loop,
|
||||
bool async,
|
||||
uint32_t seq,
|
||||
const void *data,
|
||||
size_t size,
|
||||
void *user_data)
|
||||
{
|
||||
struct impl *this = user_data;
|
||||
this->transport = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void transport_destroy(void *data)
|
||||
{
|
||||
struct impl *this = data;
|
||||
spa_log_debug(this->log, "transport %p destroy", this->transport);
|
||||
this->transport = NULL;
|
||||
spa_loop_invoke(this->data_loop, do_transport_destroy, 0, NULL, 0, true, this);
|
||||
}
|
||||
|
||||
static const struct spa_bt_transport_events transport_events = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue