Bluetooth: Protect callbacks during shutdown
- Hold the mutex during callbacks - Disable power mode before deleting hci_ Bug: 36084266 Test: Switch users repeatedly (toggles Bluetooth) Change-Id: I7e4d405e9028c3363c112a8b09c03b8aea652b7a
This commit is contained in:
parent
691a455b9f
commit
9ef1f71982
2 changed files with 12 additions and 13 deletions
|
@ -159,19 +159,13 @@ void AsyncFdWatcher::ThreadRoutine() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke the data ready callbacks if appropriate.
|
// Invoke the data ready callbacks if appropriate.
|
||||||
std::vector<decltype(watched_fds_)::value_type> saved_callbacks;
|
|
||||||
{
|
{
|
||||||
|
// Hold the mutex to make sure that the callbacks are still valid.
|
||||||
std::unique_lock<std::mutex> guard(internal_mutex_);
|
std::unique_lock<std::mutex> guard(internal_mutex_);
|
||||||
for (auto& it : watched_fds_) {
|
for (auto& it : watched_fds_) {
|
||||||
if (FD_ISSET(it.first, &read_fds)) {
|
if (FD_ISSET(it.first, &read_fds)) {
|
||||||
saved_callbacks.push_back(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& it : saved_callbacks) {
|
|
||||||
if (it.second) {
|
|
||||||
it.second(it.first);
|
it.second(it.first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,6 +268,16 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
|
||||||
}
|
}
|
||||||
|
|
||||||
void VendorInterface::Close() {
|
void VendorInterface::Close() {
|
||||||
|
// These callbacks may send HCI events (vendor-dependent), so make sure to
|
||||||
|
// StopWatching the file descriptor after this.
|
||||||
|
if (lib_interface_ != nullptr) {
|
||||||
|
bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
|
||||||
|
lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
|
||||||
|
|
||||||
|
int power_state = BT_VND_PWR_OFF;
|
||||||
|
lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
|
||||||
|
}
|
||||||
|
|
||||||
fd_watcher_.StopWatchingFileDescriptors();
|
fd_watcher_.StopWatchingFileDescriptors();
|
||||||
|
|
||||||
if (hci_ != nullptr) {
|
if (hci_ != nullptr) {
|
||||||
|
@ -276,12 +286,7 @@ void VendorInterface::Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lib_interface_ != nullptr) {
|
if (lib_interface_ != nullptr) {
|
||||||
bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
|
|
||||||
lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
|
|
||||||
|
|
||||||
lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
|
lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
|
||||||
int power_state = BT_VND_PWR_OFF;
|
|
||||||
lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lib_handle_ != nullptr) {
|
if (lib_handle_ != nullptr) {
|
||||||
|
|
Loading…
Reference in a new issue