Skip to content

Commit 647b511

Browse files
committed
SPP: Fix race condition crash by unifying thread context for resource cleanup
bug: v/80850 Rootcause: uv_loop_close() marks internal data structures as invalid, but pending callbacks in the queue still reference these invalidated structures. When uv_run() is called later, it processes the queue using corrupted pointers, leading to segmentation faults and crashes. Solution:Resolve race conditions by serializing cleanup operations: Change the cleanup operation triggered by Bluetooth adapter shutdown to be asynchronously submitted to the bttool_loop thread for sequential execution. Set the global pointer g_bttool_loop_ptr to directly point to bttool->loop, avoiding data duplication. In the on_adapter_state_changed_cb callback, use do_in_thread_loop(g_bttool_loop_ptr, bt_tool_uninit_cb, NULL) to submit the cleanup task to the bttool_loop thread, ensuring it executes sequentially in the same thread as the cleanup operation for user exit commands, thereby completely eliminating race conditions. Signed-off-by: v-chenghuijin <[email protected]>
1 parent a509681 commit 647b511

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

tools/bt_tools.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ static void* adapter_callback = NULL;
8787
static bool g_cmd_had_inited = false;
8888
bool g_auto_accept_pair = true;
8989
bond_state_t g_bond_state = BOND_STATE_NONE;
90+
static uv_loop_t* g_bttool_loop = NULL;
9091

9192
static struct {
9293
int cmd_err_code;
@@ -1595,6 +1596,12 @@ static int execute_command(void* handle, int argc, char* argv[])
15951596
return CMD_UNKNOWN;
15961597
}
15971598

1599+
static void bt_tool_uninit_cb(void* data)
1600+
{
1601+
bt_tool_uninit(g_bttool_ins);
1602+
g_bttool_loop = NULL;
1603+
}
1604+
15981605
static void on_adapter_state_changed_cb(void* cookie, bt_adapter_state_t state)
15991606
{
16001607
PRINT("Context:%p, Adapter state changed: %d", cookie, state);
@@ -1616,7 +1623,9 @@ static void on_adapter_state_changed_cb(void* cookie, bt_adapter_state_t state)
16161623
PRINT("Adapter Name: %s, Cap: %d, Class: 0x%08" PRIX32 ", Mode:%d", name, cap, class, mode);
16171624
} else if (state == BT_ADAPTER_STATE_TURNING_OFF) {
16181625
/* code */
1619-
bt_tool_uninit(g_bttool_ins);
1626+
if (g_bttool_loop && g_bttool_loop->data && !uv_loop_is_close(g_bttool_loop)) {
1627+
do_in_thread_loop(g_bttool_loop, bt_tool_uninit_cb, NULL);
1628+
}
16201629
} else if (state == BT_ADAPTER_STATE_OFF) {
16211630
/* do something */
16221631
}
@@ -1906,7 +1915,7 @@ static void bttool_thread(void* data)
19061915
before the asynchronous instance is created.
19071916
*/
19081917
uv_loop_init(&bttool->loop);
1909-
1918+
g_bttool_loop = &bttool->loop;
19101919
/* initialize synchronous or asynchronous instance.
19111920
and register callbacks.
19121921
*/

0 commit comments

Comments
 (0)