Commit 84ada302 authored by Marie Janssen's avatar Marie Janssen Committed by Gerrit Code Review
Browse files

Merge "btif: migrate from pthread locks to std::mutex"

parents d92fc91a a5764686
......@@ -22,13 +22,14 @@
#include <assert.h>
#include <ctype.h>
#include <pthread.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <mutex>
#include "bt_types.h"
#include "btcore/include/bdaddr.h"
#include "btcore/include/module.h"
......@@ -123,15 +124,14 @@ bool btif_get_address_type(const BD_ADDR bd_addr, int *p_addr_type)
return true;
}
static pthread_mutex_t lock; // protects operations on |config|.
static std::mutex config_lock; // protects operations on |config|.
static config_t *config;
static alarm_t *config_timer;
// Module lifecycle functions
static future_t *init(void) {
pthread_mutex_init(&lock, NULL);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(config_lock);
if (is_factory_reset())
delete_config_files();
......@@ -197,14 +197,11 @@ static future_t *init(void) {
LOG_EVENT_INT(BT_CONFIG_SOURCE_TAG_NUM, btif_config_source);
pthread_mutex_unlock(&lock);
return future_new_immediate(FUTURE_SUCCESS);
error:
alarm_free(config_timer);
config_free(config);
pthread_mutex_unlock(&lock);
pthread_mutex_destroy(&lock);
config_timer = NULL;
config = NULL;
btif_config_source = NOT_LOADED;
......@@ -235,7 +232,6 @@ static future_t *clean_up(void) {
alarm_free(config_timer);
config_free(config);
pthread_mutex_destroy(&lock);
config_timer = NULL;
config = NULL;
return future_new_immediate(FUTURE_SUCCESS);
......@@ -253,11 +249,8 @@ bool btif_config_has_section(const char *section) {
assert(config != NULL);
assert(section != NULL);
pthread_mutex_lock(&lock);
bool ret = config_has_section(config, section);
pthread_mutex_unlock(&lock);
return ret;
std::unique_lock<std::mutex> lock(config_lock);
return config_has_section(config, section);
}
bool btif_config_exist(const char *section, const char *key) {
......@@ -265,11 +258,8 @@ bool btif_config_exist(const char *section, const char *key) {
assert(section != NULL);
assert(key != NULL);
pthread_mutex_lock(&lock);
bool ret = config_has_key(config, section, key);
pthread_mutex_unlock(&lock);
return ret;
std::unique_lock<std::mutex> lock(config_lock);
return config_has_key(config, section, key);
}
bool btif_config_get_int(const char *section, const char *key, int *value) {
......@@ -278,11 +268,10 @@ bool btif_config_get_int(const char *section, const char *key, int *value) {
assert(key != NULL);
assert(value != NULL);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(config_lock);
bool ret = config_has_key(config, section, key);
if (ret)
*value = config_get_int(config, section, key, *value);
pthread_mutex_unlock(&lock);
return ret;
}
......@@ -292,9 +281,8 @@ bool btif_config_set_int(const char *section, const char *key, int value) {
assert(section != NULL);
assert(key != NULL);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(config_lock);
config_set_int(config, section, key, value);
pthread_mutex_unlock(&lock);
return true;
}
......@@ -306,16 +294,15 @@ bool btif_config_get_str(const char *section, const char *key, char *value, int
assert(value != NULL);
assert(size_bytes != NULL);
pthread_mutex_lock(&lock);
const char *stored_value = config_get_string(config, section, key, NULL);
pthread_mutex_unlock(&lock);
if (!stored_value)
return false;
{
std::unique_lock<std::mutex> lock(config_lock);
const char *stored_value = config_get_string(config, section, key, NULL);
if (!stored_value)
return false;
strlcpy(value, stored_value, *size_bytes);
}
strlcpy(value, stored_value, *size_bytes);
*size_bytes = strlen(value) + 1;
return true;
}
......@@ -325,10 +312,8 @@ bool btif_config_set_str(const char *section, const char *key, const char *value
assert(key != NULL);
assert(value != NULL);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(config_lock);
config_set_string(config, section, key, value);
pthread_mutex_unlock(&lock);
return true;
}
......@@ -339,9 +324,8 @@ bool btif_config_get_bin(const char *section, const char *key, uint8_t *value, s
assert(value != NULL);
assert(length != NULL);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(config_lock);
const char *value_str = config_get_string(config, section, key, NULL);
pthread_mutex_unlock(&lock);
if (!value_str)
return false;
......@@ -365,10 +349,8 @@ size_t btif_config_get_bin_length(const char *section, const char *key) {
assert(section != NULL);
assert(key != NULL);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(config_lock);
const char *value_str = config_get_string(config, section, key, NULL);
pthread_mutex_unlock(&lock);
if (!value_str)
return 0;
......@@ -393,9 +375,10 @@ bool btif_config_set_bin(const char *section, const char *key, const uint8_t *va
str[(i * 2) + 1] = lookup[value[i] & 0x0F];
}
pthread_mutex_lock(&lock);
config_set_string(config, section, key, str);
pthread_mutex_unlock(&lock);
{
std::unique_lock<std::mutex> lock(config_lock);
config_set_string(config, section, key, str);
}
osi_free(str);
return true;
......@@ -428,11 +411,8 @@ bool btif_config_remove(const char *section, const char *key) {
assert(section != NULL);
assert(key != NULL);
pthread_mutex_lock(&lock);
bool ret = config_remove_key(config, section, key);
pthread_mutex_unlock(&lock);
return ret;
std::unique_lock<std::mutex> lock(config_lock);
return config_remove_key(config, section, key);
}
void btif_config_save(void) {
......@@ -456,18 +436,15 @@ bool btif_config_clear(void) {
alarm_cancel(config_timer);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(config_lock);
config_free(config);
config = config_new_empty();
if (config == NULL) {
pthread_mutex_unlock(&lock);
if (config == NULL)
return false;
}
bool ret = config_save(config, CONFIG_FILE_PATH);
btif_config_source = RESET;
pthread_mutex_unlock(&lock);
return ret;
}
......@@ -482,13 +459,12 @@ static void btif_config_write(UNUSED_ATTR uint16_t event, UNUSED_ATTR char *p_pa
assert(config != NULL);
assert(config_timer != NULL);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(config_lock);
rename(CONFIG_FILE_PATH, CONFIG_BACKUP_PATH);
config_t *config_paired = config_new_clone(config);
btif_config_remove_unpaired(config_paired);
config_save(config_paired, CONFIG_FILE_PATH);
config_free(config_paired);
pthread_mutex_unlock(&lock);
}
static void btif_config_remove_unpaired(config_t *conf) {
......
......@@ -30,7 +30,6 @@
#include "btif_dm.h"
#include <assert.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
......@@ -39,6 +38,8 @@
#include <time.h>
#include <unistd.h>
#include <mutex>
#include <hardware/bluetooth.h>
#include "bdaddr.h"
......@@ -208,7 +209,7 @@ static uid_set_t* uid_set = NULL;
/* A circular array to keep track of the most recent bond events */
static btif_bond_event_t btif_dm_bond_events[MAX_BTIF_BOND_EVENT_ENTRIES + 1];
static pthread_mutex_t bond_event_lock;
static std::mutex bond_event_lock;
/* |btif_num_bond_events| keeps track of the total number of events and can be
greater than |MAX_BTIF_BOND_EVENT_ENTRIES| */
......@@ -297,7 +298,6 @@ static void btif_dm_data_free(uint16_t event, tBTA_DM_SEC *dm_sec)
void btif_dm_init(uid_set_t* set)
{
uid_set = set;
pthread_mutex_init(&bond_event_lock, NULL);
}
void btif_dm_cleanup(void)
......@@ -306,7 +306,6 @@ void btif_dm_cleanup(void)
uid_set_destroy(uid_set);
uid_set = NULL;
}
pthread_mutex_destroy(&bond_event_lock);
}
bt_status_t btif_in_execute_service_request(tBTA_SERVICE_ID service_id,
......@@ -3529,7 +3528,7 @@ static char* btif_get_default_local_name() {
static void btif_stats_add_bond_event(const bt_bdaddr_t *bd_addr,
bt_bond_function_t function,
bt_bond_state_t state) {
pthread_mutex_lock(&bond_event_lock);
std::unique_lock<std::mutex> lock(bond_event_lock);
btif_bond_event_t* event = &btif_dm_bond_events[btif_events_end_index];
memcpy(&event->bd_addr, bd_addr, sizeof(bt_bdaddr_t));
......@@ -3567,11 +3566,10 @@ static void btif_stats_add_bond_event(const bt_bdaddr_t *bd_addr,
event->timestamp.tv_nsec / 1000000;
metrics_pair_event(0, ts, cod, device_type);
pthread_mutex_unlock(&bond_event_lock);
}
void btif_debug_bond_event_dump(int fd) {
pthread_mutex_lock(&bond_event_lock);
std::unique_lock<std::mutex> lock(bond_event_lock);
dprintf(fd, "\nBond Events: \n");
dprintf(fd, " Total Number of events: %zu\n", btif_num_bond_events);
if (btif_num_bond_events > 0)
......@@ -3624,5 +3622,4 @@ void btif_debug_bond_event_dump(int fd) {
}
dprintf(fd, " %s %s %s %s\n", eventtime, bdaddr, func_name, bond_state);
}
pthread_mutex_unlock(&bond_event_lock);
}
......@@ -16,7 +16,7 @@
/*****************************************************************************
*
* Filename: btif_rc.c
* Filename: btif_rc.cc
*
* Description: Bluetooth AVRC implementation
*
......@@ -31,6 +31,8 @@
#include <time.h>
#include <unistd.h>
#include <mutex>
#include <hardware/bluetooth.h>
#include <hardware/bt_rc.h>
......@@ -181,7 +183,7 @@ typedef struct {
} btif_rc_device_cb_t;
typedef struct {
pthread_mutex_t lock;
std::mutex lock;
btif_rc_device_cb_t rc_multi_cb[BTIF_RC_NUM_CONN];
} rc_cb_t;
......@@ -195,7 +197,7 @@ typedef struct {
typedef struct
{
pthread_mutex_t lbllock;
std::recursive_mutex lbllock;
rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
} rc_device_t;
......@@ -275,7 +277,6 @@ static void send_metamsg_rsp (btif_rc_device_cb_t *p_dev, int index, uint8_t lab
static void register_volumechange(uint8_t label, btif_rc_device_cb_t *p_dev);
#endif
static void lbl_init();
static void lbl_destroy();
static void init_all_transactions();
static bt_status_t get_transaction(rc_transaction_t **ptransaction);
static void release_transaction(uint8_t label);
......@@ -2204,7 +2205,7 @@ static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
{
tAVRC_RESPONSE avrc_rsp;
BTIF_TRACE_EVENT("%s: event_id: %s", __func__, dump_rc_notification_event_id(event_id));
pthread_mutex_lock(&btif_rc_cb.lock);
std::unique_lock<std::mutex> lock(btif_rc_cb.lock);
memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
......@@ -2264,7 +2265,6 @@ static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
default:
BTIF_TRACE_WARNING("%s: Unhandled event ID: 0x%x", __func__, event_id);
pthread_mutex_unlock(&btif_rc_cb.lock);
return BT_STATUS_UNHANDLED;
}
......@@ -2289,7 +2289,6 @@ static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
}
}
}
pthread_mutex_unlock(&btif_rc_cb.lock);
return BT_STATUS_SUCCESS;
}
......@@ -4478,7 +4477,6 @@ static void cleanup()
memset(&btif_rc_cb.rc_multi_cb[idx], 0, sizeof(btif_rc_cb.rc_multi_cb[idx]));
}
lbl_destroy();
BTIF_TRACE_EVENT("%s: completed", __func__);
}
......@@ -4506,7 +4504,6 @@ static void cleanup_ctrl()
}
memset(&btif_rc_cb, 0, sizeof(rc_cb_t));
lbl_destroy();
BTIF_TRACE_EVENT("%s: completed", __func__);
}
......@@ -5356,7 +5353,7 @@ const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void)
*******************************************************************************/
static void initialize_transaction(int lbl)
{
pthread_mutex_lock(&device.lbllock);
std::unique_lock<std::recursive_mutex>(device.lbllock);
if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
if (alarm_is_scheduled(device.transaction[lbl].txn_timer)) {
clear_cmd_timeout(lbl);
......@@ -5365,7 +5362,6 @@ static void initialize_transaction(int lbl)
device.transaction[lbl].in_use=false;
device.transaction[lbl].handle=0;
}
pthread_mutex_unlock(&device.lbllock);
}
/*******************************************************************************
......@@ -5378,11 +5374,6 @@ static void initialize_transaction(int lbl)
void lbl_init()
{
memset(&device,0,sizeof(rc_device_t));
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&(device.lbllock), &attr);
pthread_mutexattr_destroy(&attr);
init_all_transactions();
}
......@@ -5415,7 +5406,7 @@ void init_all_transactions()
rc_transaction_t *get_transaction_by_lbl(uint8_t lbl)
{
rc_transaction_t *transaction = NULL;
pthread_mutex_lock(&device.lbllock);
std::unique_lock<std::recursive_mutex> lock(device.lbllock);
/* Determine if this is a valid label */
if (lbl < MAX_TRANSACTIONS_PER_SESSION)
......@@ -5431,7 +5422,6 @@ rc_transaction_t *get_transaction_by_lbl(uint8_t lbl)
}
}
pthread_mutex_unlock(&device.lbllock);
return transaction;
}
......@@ -5448,7 +5438,7 @@ bt_status_t get_transaction(rc_transaction_t **ptransaction)
{
bt_status_t result = BT_STATUS_NOMEM;
uint8_t i=0;
pthread_mutex_lock(&device.lbllock);
std::unique_lock<std::recursive_mutex> lock(device.lbllock);
// Check for unused transactions
for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
......@@ -5463,7 +5453,6 @@ bt_status_t get_transaction(rc_transaction_t **ptransaction)
}
}
pthread_mutex_unlock(&device.lbllock);
return result;
}
......@@ -5487,19 +5476,6 @@ void release_transaction(uint8_t lbl)
}
}
/*******************************************************************************
**
** Function lbl_destroy
**
** Description Cleanup of the mutex
**
** Returns void
*******************************************************************************/
void lbl_destroy()
{
pthread_mutex_destroy(&(device.lbllock));
}
/*******************************************************************************
** Function sleep_ms
**
......
......@@ -31,6 +31,8 @@
#include <stdlib.h>
#include <string.h>
#include <mutex>
#include <hardware/bluetooth.h>
#include <hardware/bt_sdp.h>
......@@ -42,7 +44,8 @@
#include "osi/include/allocator.h"
#include "utl.h"
static pthread_mutex_t sdp_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
// Protects the sdp_slots array from concurrent access.
static std::recursive_mutex sdp_lock;
/**
* The need for a state variable have been reduced to two states.
......@@ -108,7 +111,7 @@ bt_status_t sdp_server_init()
void sdp_server_cleanup()
{
BTIF_TRACE_DEBUG("Sdp Server %s", __func__);
pthread_mutex_lock(&sdp_lock);
std::unique_lock<std::recursive_mutex> lock(sdp_lock);
int i;
for(i = 0; i < MAX_SDP_SLOTS; i++)
{
......@@ -117,7 +120,6 @@ void sdp_server_cleanup()
*/
free_sdp_slot(i);
}
pthread_mutex_unlock(&sdp_lock);
}
int get_sdp_records_size(bluetooth_sdp_record* in_record, int count) {
......@@ -185,31 +187,26 @@ void copy_sdp_records(bluetooth_sdp_record* in_records,
* user1_ptr and
* user2_ptr. */
static int alloc_sdp_slot(bluetooth_sdp_record* in_record) {
int i;
int record_size = get_sdp_records_size(in_record, 1);
/* We are optimists here, and preallocate the record.
* This is to reduce the time we hold the sdp_lock. */
bluetooth_sdp_record* record = (bluetooth_sdp_record*)osi_malloc(record_size);
copy_sdp_records(in_record, record, 1);
/* We are optimists here, and preallocate the record.
* This is to reduce the time we hold the sdp_lock. */
pthread_mutex_lock(&sdp_lock);
for(i = 0; i < MAX_SDP_SLOTS; i++)
{
if(sdp_slots[i].state == SDP_RECORD_FREE) {
sdp_slots[i].state = SDP_RECORD_ALLOCED;
sdp_slots[i].record_data = record;
break;
}
}
pthread_mutex_unlock(&sdp_lock);
if(i >= MAX_SDP_SLOTS) {
APPL_TRACE_ERROR("%s() failed - no more free slots!", __func__);
/* Rearly the optimist is too optimistic, and cleanup is needed...*/
osi_free(record);
return -1;
}
return i;
std::unique_lock<std::recursive_mutex> lock(sdp_lock);
for (int i = 0; i < MAX_SDP_SLOTS; i++) {
if(sdp_slots[i].state == SDP_RECORD_FREE) {
sdp_slots[i].state = SDP_RECORD_ALLOCED;
sdp_slots[i].record_data = record;
return i;
}
}
}
APPL_TRACE_ERROR("%s() failed - no more free slots!", __func__);
/* Rearly the optimist is too optimistic, and cleanup is needed...*/
osi_free(record);
return -1;
}
static int free_sdp_slot(int id) {
......@@ -219,18 +216,19 @@ static int free_sdp_slot(int id) {
APPL_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
return handle;
}
pthread_mutex_lock(&sdp_lock);
handle = sdp_slots[id].sdp_handle;
sdp_slots[id].sdp_handle = 0;
if(sdp_slots[id].state != SDP_RECORD_FREE)
{
/* safe a copy of the pointer, and free after unlock() */
record = sdp_slots[id].record_data;
std::unique_lock<std::recursive_mutex> lock(sdp_lock);
handle = sdp_slots[id].sdp_handle;
sdp_slots[id].sdp_handle = 0;
if (sdp_slots[id].state != SDP_RECORD_FREE) {
/* safe a copy of the pointer, and free after unlock() */
record = sdp_slots[id].record_data;
}
sdp_slots[id].state = SDP_RECORD_FREE;
}
sdp_slots[id].state = SDP_RECORD_FREE;
pthread_mutex_unlock(&sdp_lock);
if(record != NULL) {
if (record != NULL) {
osi_free(record);
} else {
// Record have already been freed
......@@ -244,31 +242,26 @@ static int free_sdp_slot(int id) {
* SDP_RECORD_CREATE_INITIATED.
*/
static const sdp_slot_t* start_create_sdp(int id) {
sdp_slot_t* sdp_slot;
if(id >= MAX_SDP_SLOTS) {
if (id >= MAX_SDP_SLOTS) {
APPL_TRACE_ERROR("%s() failed - id %d is invalid", __func__, id);
return NULL;
}
pthread_mutex_lock(&sdp_lock);
if(sdp_slots[id].state == SDP_RECORD_ALLOCED) {
sdp_slot = &(sdp_slots[id]);
} else {
std::unique_lock<std::recursive_mutex> lock(sdp_lock);
if (sdp_slots[id].state != SDP_RECORD_ALLOCED) {
/* The record have been removed before this event occurred - e.g. deinit */
sdp_slot = NULL;
}
pthread_mutex_unlock(&sdp_lock);
if(sdp_slot == NULL) {
APPL_TRACE_ERROR("%s() failed - state for id %d is "
"sdp_slots[id].state = %d expected %d", __func__,
id, sdp_slots[id].state, SDP_RECORD_ALLOCED);
return NULL;
}
return sdp_slot;
return &(sdp_slots[id]);
}
static void set_sdp_handle(int id, int handle) {
pthread_mutex_lock(&sdp_lock);
std::unique_lock<std::recursive_mutex> lock(sdp_lock);
sdp_slots[id].sdp_handle = handle;
pthread_mutex_unlock(&sdp_lock);
BTIF_TRACE_DEBUG("%s() id=%d to handle=0x%08x", __func__, id, handle);
}
......
This diff is collapsed.
......@@ -28,6 +28,8 @@
#include <sys/types.h>
#include <unistd.h>
#include <mutex>
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
......@@ -94,7 +96,7 @@ typedef struct {
static rfc_slot_t rfc_slots[MAX_RFC_CHANNEL];
static uint32_t rfc_slot_id;
static volatile int pth = -1; // poll thread handle
static pthread_mutex_t slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static std::recursive_mutex slot_lock;
static uid_set_t* uid_set = NULL;
static rfc_slot_t *find_free_slot(void);
......@@ -134,14 +136,13 @@ void btsock_rfc_cleanup(void) {
BTA_JvDisable();
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
for (size_t i = 0; i < ARRAY_SIZE(rfc_slots); ++i) {
if (rfc_slots[i].id)
cleanup_rfc_slot(&rfc_slots[i]);
list_free(rfc_slots[i].incoming_queue);
rfc_slots[i].incoming_queue = NULL;
}
pthread_mutex_unlock(&slot_lock);
}
static rfc_slot_t *find_free_slot(void) {
......@@ -291,13 +292,12 @@ bt_status_t btsock_rfc_listen(const char *service_name, const uint8_t *service_u
}
}
int status = BT_STATUS_FAIL;
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = alloc_rfc_slot(NULL, service_name, service_uuid, channel, flags, true);
if (!slot) {
LOG_ERROR(LOG_TAG, "%s unable to allocate RFCOMM slot.", __func__);
goto out;
return BT_STATUS_FAIL;
}
APPL_TRACE_DEBUG("BTA_JvGetChannelId: service_name: %s - channel: %d", service_name, channel);
BTA_JvGetChannelId(BTA_JV_CONN_TYPE_RFCOMM, UINT_TO_PTR(slot->id), channel);
......@@ -313,11 +313,7 @@ bt_status_t btsock_rfc_listen(const char *service_name, const uint8_t *service_u
slot->app_uid = app_uid;
btsock_thread_add_fd(pth, slot->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION, slot->id);
status = BT_STATUS_SUCCESS;
out:;
pthread_mutex_unlock(&slot_lock);
return (bt_status_t)status;
return BT_STATUS_SUCCESS;
}
bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t *service_uuid, int channel, int *sock_fd, int flags, int app_uid) {
......@@ -331,13 +327,12 @@ bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t *servic
if (!is_init_done())
return BT_STATUS_NOT_READY;
int status = BT_STATUS_FAIL;
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = alloc_rfc_slot(bd_addr, NULL, service_uuid, channel, flags, false);
if (!slot) {
LOG_ERROR(LOG_TAG, "%s unable to allocate RFCOMM slot.", __func__);
goto out;
return BT_STATUS_FAIL;
}
if (is_uuid_empty(service_uuid)) {
......@@ -345,13 +340,13 @@ bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t *servic
if (ret != BTA_JV_SUCCESS) {
LOG_ERROR(LOG_TAG, "%s unable to initiate RFCOMM connection: %d", __func__, ret);
cleanup_rfc_slot(slot);
goto out;
return BT_STATUS_FAIL;
}
if (!send_app_scn(slot)) {
LOG_ERROR(LOG_TAG, "%s unable to send channel number.", __func__);
cleanup_rfc_slot(slot);
goto out;
return BT_STATUS_FAIL;
}
} else {
tSDP_UUID sdp_uuid;
......@@ -372,11 +367,8 @@ bt_status_t btsock_rfc_connect(const bt_bdaddr_t *bd_addr, const uint8_t *servic
slot->app_fd = INVALID_FD; // Drop our reference to the fd.
slot->app_uid = app_uid;
btsock_thread_add_fd(pth, slot->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, slot->id);
status = BT_STATUS_SUCCESS;
out:;
pthread_mutex_unlock(&slot_lock);
return (bt_status_t)status;
return BT_STATUS_SUCCESS;
}
static int create_server_sdp_record(rfc_slot_t *slot) {
......@@ -456,96 +448,78 @@ static bool send_app_connect_signal(int fd, const bt_bdaddr_t* addr, int channel
}
static void on_cl_rfc_init(tBTA_JV_RFCOMM_CL_INIT *p_init, uint32_t id) {
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (!slot)
goto out;
return;
if (p_init->status == BTA_JV_SUCCESS)
if (p_init->status == BTA_JV_SUCCESS) {
slot->rfc_handle = p_init->handle;
else
} else {
cleanup_rfc_slot(slot);
out:;
pthread_mutex_unlock(&slot_lock);
}
}
static void on_srv_rfc_listen_started(tBTA_JV_RFCOMM_START *p_start, uint32_t id) {
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (!slot)
goto out;
return;
if (p_start->status == BTA_JV_SUCCESS) {
slot->rfc_handle = p_start->handle;
} else
} else {
cleanup_rfc_slot(slot);
out:;
pthread_mutex_unlock(&slot_lock);
}
}
static uint32_t on_srv_rfc_connect(tBTA_JV_RFCOMM_SRV_OPEN *p_open, uint32_t id) {
uint32_t new_listen_slot_id = 0;
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *accept_rs;
rfc_slot_t *srv_rs = find_rfc_slot_by_id(id);
if (!srv_rs)
goto out;
return 0;
accept_rs = create_srv_accept_rfc_slot(srv_rs, (const bt_bdaddr_t *)p_open->rem_bda, p_open->handle, p_open->new_listen_handle);
if (!accept_rs)
goto out;
return 0;
// Start monitoring the socket.
btsock_thread_add_fd(pth, srv_rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_EXCEPTION, srv_rs->id);
btsock_thread_add_fd(pth, accept_rs->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, accept_rs->id);
send_app_connect_signal(srv_rs->fd, &accept_rs->addr, srv_rs->scn, 0, accept_rs->app_fd);
accept_rs->app_fd = INVALID_FD; // Ownership of the application fd has been transferred.
new_listen_slot_id = srv_rs->id;
out:;
pthread_mutex_unlock(&slot_lock);
return new_listen_slot_id;
return srv_rs->id;
}
static void on_cli_rfc_connect(tBTA_JV_RFCOMM_OPEN *p_open, uint32_t id) {
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (!slot)
goto out;
return;
if (p_open->status != BTA_JV_SUCCESS) {
cleanup_rfc_slot(slot);
goto out;
return;
}
slot->rfc_port_handle = BTA_JvRfcommGetPortHdl(p_open->handle);
memcpy(slot->addr.address, p_open->rem_bda, 6);
if (send_app_connect_signal(slot->fd, &slot->addr, slot->scn, 0, -1))
if (send_app_connect_signal(slot->fd, &slot->addr, slot->scn, 0, -1)) {
slot->f.connected = true;
else
} else {
LOG_ERROR(LOG_TAG, "%s unable to send connect completion signal to caller.", __func__);
out:;
pthread_mutex_unlock(&slot_lock);
}
}
static void on_rfc_close(UNUSED_ATTR tBTA_JV_RFCOMM_CLOSE *p_close, uint32_t id) {
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
// rfc_handle already closed when receiving rfcomm close event from stack.
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (slot)
cleanup_rfc_slot(slot);
pthread_mutex_unlock(&slot_lock);
}
static void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE *p, uint32_t id) {
......@@ -555,7 +529,7 @@ static void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE *p, uint32_t id) {
}
int app_uid = -1;
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (slot) {
......@@ -565,13 +539,11 @@ static void on_rfc_write_done(tBTA_JV_RFCOMM_WRITE *p, uint32_t id) {
}
}
pthread_mutex_unlock(&slot_lock);
uid_set_add_tx(uid_set, app_uid, p->len);
}
static void on_rfc_outgoing_congest(tBTA_JV_RFCOMM_CONG *p, uint32_t id) {
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (slot) {
......@@ -579,8 +551,6 @@ static void on_rfc_outgoing_congest(tBTA_JV_RFCOMM_CONG *p, uint32_t id) {
if (!slot->f.outgoing_congest)
btsock_thread_add_fd(pth, slot->fd, BTSOCK_RFCOMM, SOCK_THREAD_FD_RD, slot->id);
}
pthread_mutex_unlock(&slot_lock);
}
static void *rfcomm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
......@@ -634,12 +604,11 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
switch(event) {
case BTA_JV_GET_SCN_EVT:
{
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t* rs = find_rfc_slot_by_id(id);
int new_scn = p_data->scn;
if(rs && (new_scn != 0))
{
if (rs && (new_scn != 0)) {
rs->scn = new_scn;
/* BTA_JvCreateRecordByUser will only create a record if a UUID is specified,
* else it just allocate a RFC channel and start the RFCOMM thread - needed
......@@ -649,12 +618,12 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
* has received the RFCOMM and L2CAP channel numbers through the sockets.*/
// Send channel ID to java layer
if(!send_app_scn(rs)){
if (!send_app_scn(rs)) {
//closed
APPL_TRACE_DEBUG("send_app_scn() failed, close rs->id:%d", rs->id);
cleanup_rfc_slot(rs);
} else {
if(rs->is_service_uuid_valid == true) {
if (rs->is_service_uuid_valid == true) {
// We already have data for SDP record, create it (RFC-only profiles)
BTA_JvCreateRecordByUser(UINT_TO_PTR(rs->id));
} else {
......@@ -665,11 +634,10 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
rfcomm_cback, UINT_TO_PTR(rs->id));
}
}
} else if(rs) {
} else if (rs) {
APPL_TRACE_ERROR("jv_dm_cback: Error: allocate channel %d, slot found:%p", rs->scn, rs);
cleanup_rfc_slot(rs);
}
pthread_mutex_unlock(&slot_lock);
break;
}
case BTA_JV_GET_PSM_EVT:
......@@ -678,10 +646,11 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
on_l2cap_psm_assigned(id, p_data->psm);
break;
}
case BTA_JV_CREATE_RECORD_EVT: {
pthread_mutex_lock(&slot_lock);
case BTA_JV_CREATE_RECORD_EVT:
{
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (slot && create_server_sdp_record(slot)) {
// Start the rfcomm server after sdp & channel # assigned.
BTA_JvRfcommStartServer(slot->security, slot->role, slot->scn, MAX_RFC_SESSION, rfcomm_cback, (void *)(uintptr_t)slot->id);
......@@ -689,13 +658,12 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
APPL_TRACE_ERROR("jv_dm_cback: cannot start server, slot found:%p", slot);
cleanup_rfc_slot(slot);
}
pthread_mutex_unlock(&slot_lock);
break;
}
case BTA_JV_DISCOVERY_COMP_EVT: {
pthread_mutex_lock(&slot_lock);
case BTA_JV_DISCOVERY_COMP_EVT:
{
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (p_data->disc_comp.status == BTA_JV_SUCCESS && p_data->disc_comp.scn) {
if (slot && slot->f.doing_sdp_request) {
......@@ -726,8 +694,6 @@ static void jv_dm_cback(tBTA_JV_EVT event, tBTA_JV *p_data, void *user_data) {
slot->f.pending_sdp_request = false;
slot->f.doing_sdp_request = true;
}
pthread_mutex_unlock(&slot_lock);
break;
}
......@@ -799,13 +765,11 @@ static bool flush_incoming_que_on_wr_signal(rfc_slot_t *slot) {
}
void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t user_id) {
pthread_mutex_lock(&slot_lock);
bool need_close = false;
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(user_id);
if (!slot)
goto out;
return;
// Data available from app, tell stack we have outgoing data.
if (flags & SOCK_THREAD_FD_RD && !slot->f.server) {
......@@ -835,22 +799,17 @@ void btsock_rfc_signaled(UNUSED_ATTR int fd, int flags, uint32_t user_id) {
if (need_close || ioctl(slot->fd, FIONREAD, &size) != 0 || !size)
cleanup_rfc_slot(slot);
}
out:;
pthread_mutex_unlock(&slot_lock);
}
int bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf) {
int app_uid = -1;
uint64_t bytes_rx = 0;
pthread_mutex_lock(&slot_lock);
int ret = 0;
uint32_t id = (uintptr_t)user_data;
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (!slot)
goto out;
return 0;
app_uid = slot->app_uid;
bytes_rx = p_buf->len;
......@@ -877,56 +836,43 @@ int bta_co_rfc_data_incoming(void *user_data, BT_HDR *p_buf) {
list_append(slot->incoming_queue, p_buf);
}
out:;
pthread_mutex_unlock(&slot_lock);
uid_set_add_rx(uid_set, app_uid, bytes_rx);
return ret; // Return 0 to disable data flow.
}
int bta_co_rfc_data_outgoing_size(void *user_data, int *size) {
pthread_mutex_lock(&slot_lock);
uint32_t id = (uintptr_t)user_data;
int ret = false;
*size = 0;
std::unique_lock<std::recursive_mutex> lock(slot_lock);
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (!slot)
goto out;
return false;
if (ioctl(slot->fd, FIONREAD, size) == 0) {
ret = true;
} else {
if (ioctl(slot->fd, FIONREAD, size) != 0) {
LOG_ERROR(LOG_TAG, "%s unable to determine bytes remaining to be read on fd %d: %s", __func__, slot->fd, strerror(errno));
cleanup_rfc_slot(slot);
return false;
}
out:;
pthread_mutex_unlock(&slot_lock);
return ret;
return true;
}
int bta_co_rfc_data_outgoing(void *user_data, uint8_t *buf, uint16_t size) {
pthread_mutex_lock(&slot_lock);
std::unique_lock<std::recursive_mutex> lock(slot_lock);
uint32_t id = (uintptr_t)user_data;
int ret = false;
rfc_slot_t *slot = find_rfc_slot_by_id(id);
if (!slot)
goto out;
return false;
ssize_t received;
OSI_NO_INTR(received = recv(slot->fd, buf, size, 0));
if(received == size) {
ret = true;
} else {
if(received != size) {
LOG_ERROR(LOG_TAG, "%s error receiving RFCOMM data from app: %s", __func__, strerror(errno));
cleanup_rfc_slot(slot);
return false;
}
out:;
pthread_mutex_unlock(&slot_lock);
return ret;
return true;
}
......@@ -26,6 +26,8 @@
#include <sys/types.h>
#include <unistd.h>
#include <mutex>
#include <hardware/bluetooth.h>
#include <hardware/bt_sock.h>
......@@ -82,9 +84,9 @@ static void connect_completed_cb(uint16_t sco_handle);
static void disconnect_completed_cb(uint16_t sco_handle);
static void socket_read_ready_cb(socket_t *socket, void *context);
// |lock| protects all of the static variables below and
// |sco_lock| protects all of the static variables below and
// calls into the BTM layer.
static pthread_mutex_t lock;
static std::mutex sco_lock;
static list_t *sco_sockets; // Owns a collection of sco_socket_t objects.
static sco_socket_t *listen_sco_socket; // Not owned, do not free.
static thread_t *thread; // Not owned, do not free.
......@@ -96,8 +98,6 @@ bt_status_t btsock_sco_init(thread_t *thread_) {
if (!sco_sockets)
return BT_STATUS_FAIL;
pthread_mutex_init(&lock, NULL);
thread = thread_;
BTM_SetEScoMode(BTM_LINK_TYPE_ESCO, &sco_parameters);
......@@ -107,33 +107,30 @@ bt_status_t btsock_sco_init(thread_t *thread_) {
bt_status_t btsock_sco_cleanup(void) {
list_free(sco_sockets);
sco_sockets = NULL;
pthread_mutex_destroy(&lock);
return BT_STATUS_SUCCESS;
}
bt_status_t btsock_sco_listen(int *sock_fd, UNUSED_ATTR int flags) {
assert(sock_fd != NULL);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(sco_lock);
sco_socket_t *sco_socket = sco_socket_establish_locked(true, NULL, sock_fd);
if (sco_socket) {
BTM_RegForEScoEvts(sco_socket->sco_handle, connection_request_cb);
listen_sco_socket = sco_socket;
}
if (!sco_socket)
return BT_STATUS_FAIL;
pthread_mutex_unlock(&lock);
BTM_RegForEScoEvts(sco_socket->sco_handle, connection_request_cb);
listen_sco_socket = sco_socket;
return sco_socket ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
return BT_STATUS_SUCCESS;
}
bt_status_t btsock_sco_connect(const bt_bdaddr_t *bd_addr, int *sock_fd, UNUSED_ATTR int flags) {
assert(bd_addr != NULL);
assert(sock_fd != NULL);
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(sco_lock);
sco_socket_t *sco_socket = sco_socket_establish_locked(false, bd_addr, sock_fd);
pthread_mutex_unlock(&lock);
return (sco_socket != NULL) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
}
......@@ -220,7 +217,7 @@ static void connection_request_cb(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *data)
if (event != BTM_ESCO_CONN_REQ_EVT)
return;
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(sco_lock);
const tBTM_ESCO_CONN_REQ_EVT_DATA *conn_data = &data->conn_evt;
sco_socket_t *sco_socket = sco_socket_find_locked(conn_data->sco_inx);
......@@ -264,24 +261,21 @@ static void connection_request_cb(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *data)
BTM_RegForEScoEvts(listen_sco_socket->sco_handle, connection_request_cb);
BTM_EScoConnRsp(conn_data->sco_inx, HCI_SUCCESS, NULL);
pthread_mutex_unlock(&lock);
return;
error:;
pthread_mutex_unlock(&lock);
if (client_fd != INVALID_FD)
close(client_fd);
BTM_EScoConnRsp(conn_data->sco_inx, HCI_ERR_HOST_REJECT_RESOURCES, NULL);
}
static void connect_completed_cb(uint16_t sco_handle) {
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(sco_lock);
sco_socket_t *sco_socket = sco_socket_find_locked(sco_handle);
if (!sco_socket) {
LOG_ERROR(LOG_TAG, "%s SCO socket not found on connect for handle: %hu", __func__, sco_handle);
goto out;
return;
}
// If sco_socket->socket was closed, we should tear down because there is no app-level
......@@ -289,32 +283,26 @@ static void connect_completed_cb(uint16_t sco_handle) {
if (!sco_socket->socket) {
BTM_RemoveSco(sco_socket->sco_handle);
list_remove(sco_sockets, sco_socket);
goto out;
return;
}
sco_socket->connect_completed = true;
out:;
pthread_mutex_unlock(&lock);
}
static void disconnect_completed_cb(uint16_t sco_handle) {
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(sco_lock);
sco_socket_t *sco_socket = sco_socket_find_locked(sco_handle);
if (!sco_socket) {
LOG_ERROR(LOG_TAG, "%s SCO socket not found on disconnect for handle: %hu", __func__, sco_handle);
goto out;
return;
}
list_remove(sco_sockets, sco_socket);
out:;
pthread_mutex_unlock(&lock);
}
static void socket_read_ready_cb(UNUSED_ATTR socket_t *socket, void *context) {
pthread_mutex_lock(&lock);
std::unique_lock<std::mutex> lock(sco_lock);
sco_socket_t *sco_socket = (sco_socket_t *)context;
socket_free(sco_socket->socket);
......@@ -332,6 +320,4 @@ static void socket_read_ready_cb(UNUSED_ATTR socket_t *socket, void *context) {
if (sco_socket == listen_sco_socket)
listen_sco_socket = NULL;
}
pthread_mutex_unlock(&lock);
}
......@@ -18,11 +18,10 @@
/************************************************************************************
*
* Filename: btif_sock_thread.c
* Filename: btif_sock_thread.cc
*
* Description: socket select thread
*
*
***********************************************************************************/
#define LOG_TAG "bt_btif_sock"
......@@ -47,6 +46,8 @@
#include <time.h>
#include <unistd.h>
#include <mutex>
#include "bta_api.h"
#include "btif_common.h"
#include "btif_sock.h"
......@@ -102,7 +103,7 @@ static inline void close_cmd_fd(int h);
static inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id);
static pthread_mutex_t thread_slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static std::recursive_mutex thread_slot_lock;
static inline int create_thread(void *(*start_routine)(void *), void * arg,
pthread_t * thread_id)
......@@ -112,7 +113,7 @@ static inline int create_thread(void *(*start_routine)(void *), void * arg,
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
int policy;
int min_pri=0;
int ret = -1;
int ret = -1;
struct sched_param param;
if ((ret = pthread_create(thread_id, &thread_attr, start_routine, arg))!=0 )
......@@ -133,8 +134,9 @@ static inline int create_thread(void *(*start_routine)(void *), void * arg,
static void init_poll(int cmd_fd);
static int alloc_thread_slot()
{
std::unique_lock<std::recursive_mutex> lock(thread_slot_lock);
int i;
//revserd order to save guard uninitialized access to 0 index
// reversed order to save guard uninitialized access to 0 index
for(i = MAX_THREAD - 1; i >=0; i--)
{
APPL_TRACE_DEBUG("ts[%d].used:%d", i, ts[i].used);
......@@ -179,9 +181,7 @@ int btsock_thread_init()
int btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback)
{
asrt(callback || cmd_callback);
pthread_mutex_lock(&thread_slot_lock);
int h = alloc_thread_slot();
pthread_mutex_unlock(&thread_slot_lock);
APPL_TRACE_DEBUG("alloc_thread_slot ret:%d", h);
if(h >= 0)
{
......@@ -366,9 +366,7 @@ int btsock_thread_exit(int h)
if (ret == sizeof(cmd)) {
pthread_join(ts[h].thread_id, 0);
pthread_mutex_lock(&thread_slot_lock);
free_thread_slot(h);
pthread_mutex_unlock(&thread_slot_lock);
return true;
}
return false;
......
......@@ -16,13 +16,13 @@
/************************************************************************************
*
* Filename: btif_uid.c
* Filename: btif_uid.cc
*
* Description: Contains data structures and functions for keeping track of
* socket usage per app UID.
*
***********************************************************************************/
#include <pthread.h>
#include <mutex>
#include "bt_common.h"
#include "btif_uid.h"
......@@ -33,18 +33,17 @@ typedef struct uid_set_node_t {
} uid_set_node_t;
typedef struct uid_set_t {
pthread_mutex_t lock;
std::mutex lock;
uid_set_node_t* head;
} uid_set_t;
uid_set_t* uid_set_create(void) {
uid_set_t* set = (uid_set_t*)osi_calloc(sizeof(uid_set_t));
pthread_mutex_init(&set->lock, NULL);
return set;
}
void uid_set_destroy(uid_set_t* set) {
pthread_mutex_lock(&set->lock);
std::unique_lock<std::mutex> lock(set->lock);
uid_set_node_t* node = set->head;
while (node) {
uid_set_node_t* temp = node;
......@@ -52,8 +51,6 @@ void uid_set_destroy(uid_set_t* set) {
osi_free(temp);
}
set->head = NULL;
pthread_mutex_unlock(&set->lock);
pthread_mutex_destroy(&set->lock);
osi_free(set);
}
......@@ -74,29 +71,25 @@ static uid_set_node_t* uid_set_find_or_create_node(uid_set_t* set, int32_t app_u
}
void uid_set_add_tx(uid_set_t* set, int32_t app_uid, uint64_t bytes) {
if (app_uid == -1 || bytes == 0) {
if (app_uid == -1 || bytes == 0)
return;
}
pthread_mutex_lock(&set->lock);
std::unique_lock<std::mutex> lock(set->lock);
uid_set_node_t* node = uid_set_find_or_create_node(set, app_uid);
node->data.tx_bytes += bytes;
pthread_mutex_unlock(&set->lock);
}
void uid_set_add_rx(uid_set_t* set, int32_t app_uid, uint64_t bytes) {
if (app_uid == -1 || bytes == 0) {
if (app_uid == -1 || bytes == 0)
return;
}
pthread_mutex_lock(&set->lock);
std::unique_lock<std::mutex> lock(set->lock);
uid_set_node_t* node = uid_set_find_or_create_node(set, app_uid);
node->data.rx_bytes += bytes;
pthread_mutex_unlock(&set->lock);
}
bt_uid_traffic_t* uid_set_read_and_clear(uid_set_t* set) {
pthread_mutex_lock(&set->lock);
std::unique_lock<std::mutex> lock(set->lock);
// Find the length
size_t len = 0;
......@@ -125,7 +118,5 @@ bt_uid_traffic_t* uid_set_read_and_clear(uid_set_t* set) {
// Mark the last entry
data->app_uid = -1;
pthread_mutex_unlock(&set->lock);
return result;
}
......@@ -21,9 +21,9 @@
#include "osi/include/allocation_tracker.h"
#include <assert.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <mutex>
#include <unordered_map>
#include "osi/include/allocator.h"
......@@ -40,10 +40,11 @@ typedef struct {
static const size_t canary_size = 8;
static char canary[canary_size];
static std::unordered_map<void*, allocation_t*> allocations;
static pthread_mutex_t lock;
static std::mutex tracker_lock;
static bool enabled = false;
void allocation_tracker_init(void) {
std::unique_lock<std::mutex> lock(tracker_lock);
if (enabled)
return;
......@@ -53,39 +54,32 @@ void allocation_tracker_init(void) {
LOG_DEBUG(LOG_TAG, "canary initialized");
pthread_mutex_init(&lock, NULL);
pthread_mutex_lock(&lock);
enabled = true;
pthread_mutex_unlock(&lock);
}
// Test function only. Do not call in the normal course of operations.
void allocation_tracker_uninit(void) {
std::unique_lock<std::mutex> lock(tracker_lock);
if (!enabled)
return;
pthread_mutex_lock(&lock);
allocations.clear();
enabled = false;
pthread_mutex_unlock(&lock);
}
void allocation_tracker_reset(void) {
std::unique_lock<std::mutex> lock(tracker_lock);
if (!enabled)
return;
pthread_mutex_lock(&lock);
allocations.clear();
pthread_mutex_unlock(&lock);
}
size_t allocation_tracker_expect_no_allocations(void) {
std::unique_lock<std::mutex> lock(tracker_lock);
if (!enabled)
return 0;
pthread_mutex_lock(&lock);
size_t unfreed_memory_size = 0;
for (const auto &entry : allocations) {
......@@ -96,38 +90,35 @@ size_t allocation_tracker_expect_no_allocations(void) {
}
}
pthread_mutex_unlock(&lock);
return unfreed_memory_size;
}
void *allocation_tracker_notify_alloc(uint8_t allocator_id, void *ptr, size_t requested_size) {
if (!enabled || !ptr)
return ptr;
char *return_ptr = (char *)ptr;
return_ptr += canary_size;
char *return_ptr;
{
std::unique_lock<std::mutex> lock(tracker_lock);
if (!enabled || !ptr)
return ptr;
return_ptr = ((char *)ptr) + canary_size;
auto map_entry = allocations.find(return_ptr);
allocation_t *allocation;
if (map_entry != allocations.end()) {
allocation = map_entry->second;
assert(allocation->freed); // Must have been freed before
} else {
allocation = (allocation_t *)calloc(1, sizeof(allocation_t));
allocations[return_ptr] = allocation;
}
pthread_mutex_lock(&lock);
allocation->allocator_id = allocator_id;
allocation->freed = false;
allocation->size = requested_size;
allocation->ptr = return_ptr;
auto map_entry = allocations.find(return_ptr);
allocation_t *allocation;
if (map_entry != allocations.end()) {
allocation = map_entry->second;
assert(allocation->freed); // Must have been freed before
} else {
allocation = (allocation_t *)calloc(1, sizeof(allocation_t));
allocations[return_ptr] = allocation;
}
allocation->allocator_id = allocator_id;
allocation->freed = false;
allocation->size = requested_size;
allocation->ptr = return_ptr;
pthread_mutex_unlock(&lock);
// Add the canary on both sides
memcpy(return_ptr - canary_size, canary, canary_size);
memcpy(return_ptr + requested_size, canary, canary_size);
......@@ -136,11 +127,10 @@ void *allocation_tracker_notify_alloc(uint8_t allocator_id, void *ptr, size_t re
}
void *allocation_tracker_notify_free(UNUSED_ATTR uint8_t allocator_id, void *ptr) {
std::unique_lock<std::mutex> lock(tracker_lock);
if (!enabled || !ptr)
return ptr;
pthread_mutex_lock(&lock);
auto map_entry = allocations.find(ptr);
assert(map_entry != allocations.end());
allocation_t *allocation = map_entry->second;
......@@ -162,8 +152,6 @@ void *allocation_tracker_notify_free(UNUSED_ATTR uint8_t allocator_id, void *ptr
// as the allocation entry will not be present.
allocations.erase(ptr);
pthread_mutex_unlock(&lock);
return ((char *)ptr) - canary_size;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment