OSDN Git Service

Bluetooth: Protect callbacks during shutdown am: 9ef1f71982 am: d222c44873
authorMyles Watson <mylesgw@google.com>
Thu, 9 Mar 2017 20:39:18 +0000 (20:39 +0000)
committerandroid-build-merger <android-build-merger@google.com>
Thu, 9 Mar 2017 20:39:18 +0000 (20:39 +0000)
am: a6a12995e5

Change-Id: I7548d7550b7448f3ed9e1b19bc5a8b8cc6b6a553

bluetooth/1.0/default/async_fd_watcher.cc
bluetooth/1.0/default/vendor_interface.cc

index 2f23a69..05ac537 100644 (file)
@@ -159,19 +159,13 @@ void AsyncFdWatcher::ThreadRoutine() {
     }
 
     // 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_);
       for (auto& it : watched_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);
+        }
       }
     }
   }
index 6d3b56f..2576eca 100644 (file)
@@ -268,6 +268,16 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
 }
 
 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();
 
   if (hci_ != nullptr) {
@@ -276,12 +286,7 @@ void VendorInterface::Close() {
   }
 
   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);
-    int power_state = BT_VND_PWR_OFF;
-    lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
   }
 
   if (lib_handle_ != nullptr) {