OSDN Git Service

BT: Use static lock to avoid race while cleanup
authorGurpreet Ghai <gghai@codeaurora.org>
Sun, 20 Aug 2017 08:52:27 +0000 (14:22 +0530)
committerMyles Watson <mylesgw@google.com>
Thu, 9 Nov 2017 20:10:42 +0000 (20:10 +0000)
Problem:
The functions protected by mutex lock are called after cleanup
during shutdown. During this race condition, the structure set does not
exist and cause crash.

Steps:
Bluetooth on/off automation

Failure:
Bluetooth process crashes

RootCause:
Mutex is accessed after it is destroyed because of other thread calling
the function.

Fix:
Changed mutex lock to static type so that it exist and protect
the set structure even after cleanup.

Test: manual

Bug: 66921327

Change-Id: I8d1f5d5d607100ab73aec722a27688dae45cc323

btif/src/btif_uid.cc

index 543308d..4ee5fe8 100644 (file)
 #include "bt_common.h"
 #include "btif_uid.h"
 
+static std::mutex set_lock;
+
 typedef struct uid_set_node_t {
   struct uid_set_node_t* next;
   bt_uid_traffic_t data;
 } uid_set_node_t;
 
 typedef struct uid_set_t {
-  std::mutex lock;
   uid_set_node_t* head;
 } uid_set_t;
 
@@ -43,7 +44,7 @@ uid_set_t* uid_set_create(void) {
 }
 
 void uid_set_destroy(uid_set_t* set) {
-  std::unique_lock<std::mutex> lock(set->lock);
+  std::unique_lock<std::mutex> guard(set_lock);
   uid_set_node_t* node = set->head;
   while (node) {
     uid_set_node_t* temp = node;
@@ -74,7 +75,7 @@ static uid_set_node_t* uid_set_find_or_create_node(uid_set_t* set,
 void uid_set_add_tx(uid_set_t* set, int32_t app_uid, uint64_t bytes) {
   if (app_uid == -1 || bytes == 0) return;
 
-  std::unique_lock<std::mutex> lock(set->lock);
+  std::unique_lock<std::mutex> guard(set_lock);
   uid_set_node_t* node = uid_set_find_or_create_node(set, app_uid);
   node->data.tx_bytes += bytes;
 }
@@ -82,13 +83,13 @@ void uid_set_add_tx(uid_set_t* set, int32_t app_uid, uint64_t bytes) {
 void uid_set_add_rx(uid_set_t* set, int32_t app_uid, uint64_t bytes) {
   if (app_uid == -1 || bytes == 0) return;
 
-  std::unique_lock<std::mutex> lock(set->lock);
+  std::unique_lock<std::mutex> guard(set_lock);
   uid_set_node_t* node = uid_set_find_or_create_node(set, app_uid);
   node->data.rx_bytes += bytes;
 }
 
 bt_uid_traffic_t* uid_set_read_and_clear(uid_set_t* set) {
-  std::unique_lock<std::mutex> lock(set->lock);
+  std::unique_lock<std::mutex> guard(set_lock);
 
   // Find the length
   size_t len = 0;