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:
Pauli Virtanen 2021-01-02 02:02:58 +02:00 committed by Wim Taymans
parent a5e52c07b1
commit da2fa8a599
4 changed files with 61 additions and 4 deletions

View file

@ -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 = {

View file

@ -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,

View file

@ -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 = {

View file

@ -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 = {