Skip to content

Commit b1ecc40

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 (e.g., set to -1), 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:We modified the adapter state change callback (on_adapter_state_changed_cb) in bt_tools.c. When the adapter state is detected to be turning off, instead of directly calling the cleanup function, the task bt_tool_uninit_cb is now dispatched to the bttool_loop thread for sequential execution via do_in_thread_loop. This approach ensures all resource cleanup operations—including the critical spp_command_uninit call—are completed sequentially within the same thread context, completely eliminating the possibility of concurrent access. Signed-off-by: v-chenghuijin <v-chenghuijin@xiaomi.com>
1 parent fe34376 commit b1ecc40

File tree

4 files changed

+18
-13
lines changed

4 files changed

+18
-13
lines changed

framework/common/uv_thread_loop.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,8 @@ void thread_loop_exit(uv_loop_t* loop)
223223
uv_sem_wait(&priv->exited);
224224
uv_sem_destroy(&priv->exited);
225225
} else {
226-
if (!uv_loop_is_close(loop)) {
227-
uv_run(loop, UV_RUN_ONCE);
228-
(void)uv_loop_close(loop);
229-
}
226+
uv_run(loop, UV_RUN_ONCE);
227+
(void)uv_loop_close(loop);
230228
}
231229

232230
uv_mutex_lock(&priv->msg_lock);

service/common/service_loop.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,8 @@ void service_loop_exit(void)
287287
uv_sem_wait(&loop->exited);
288288
uv_sem_destroy(&loop->exited);
289289
} else {
290-
if (!uv_loop_is_close(handle)) {
291-
uv_run(handle, UV_RUN_ONCE);
292-
(void)uv_loop_close(handle);
293-
}
290+
uv_run(handle, UV_RUN_ONCE);
291+
(void)uv_loop_close(handle);
294292
}
295293

296294
uv_mutex_lock(&loop->msg_lock);

tools/bt_tools.c

Lines changed: 10 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 bttool_loop;
9091

9192
static struct {
9293
int cmd_err_code;
@@ -1595,6 +1596,11 @@ 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+
}
1603+
15981604
static void on_adapter_state_changed_cb(void* cookie, bt_adapter_state_t state)
15991605
{
16001606
PRINT("Context:%p, Adapter state changed: %d", cookie, state);
@@ -1616,7 +1622,9 @@ static void on_adapter_state_changed_cb(void* cookie, bt_adapter_state_t state)
16161622
PRINT("Adapter Name: %s, Cap: %d, Class: 0x%08" PRIX32 ", Mode:%d", name, cap, class, mode);
16171623
} else if (state == BT_ADAPTER_STATE_TURNING_OFF) {
16181624
/* code */
1619-
bt_tool_uninit(g_bttool_ins);
1625+
if (bttool_loop.data) {
1626+
do_in_thread_loop(&bttool_loop, bt_tool_uninit_cb, NULL);
1627+
}
16201628
} else if (state == BT_ADAPTER_STATE_OFF) {
16211629
/* do something */
16221630
}
@@ -1906,7 +1914,7 @@ static void bttool_thread(void* data)
19061914
before the asynchronous instance is created.
19071915
*/
19081916
uv_loop_init(&bttool->loop);
1909-
1917+
memcpy(&bttool_loop, &bttool->loop, sizeof(uv_loop_t));
19101918
/* initialize synchronous or asynchronous instance.
19111919
and register callbacks.
19121920
*/

tools/spp.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
***************************************************************************/
16-
#include <stdlib.h>
17-
#include <string.h>
1816

19-
#include "bt_config.h"
2017
#include "bt_list.h"
2118
#include "bt_spp.h"
2219
#include "bt_time.h"
2320
#include "bt_tools.h"
2421
#include "bt_uuid.h"
2522
#include "euv_pipe.h"
2623
#include "uv_thread_loop.h"
24+
#include <inttypes.h>
25+
#include <stdlib.h>
26+
#include <string.h>
27+
#include <syslog.h>
2728

2829
typedef struct {
2930
struct list_node node;

0 commit comments

Comments
 (0)