From 0872cc31abb3990b0892898f45bf2c87da627e4c Mon Sep 17 00:00:00 2001 From: Mattias Agren Date: Thu, 19 Apr 2012 23:10:53 +0200 Subject: Ensure UIPC task is fully shutdown upon termination of btif media task. Change-Id: Ie924cd324c85ca2037e94402a145a4eeeed62511 --- btif/include/btif_av.h | 0 btif/include/btif_common.h | 0 btif/src/btif_core.c | 6 +++--- btif/src/btif_media_task.c | 36 ++++++++++++++++++++++++++---------- conf/bt_did.conf | 0 udrv/ulinux/uipc.c | 45 +++++++++++++++++++++++++++++++++------------ 6 files changed, 62 insertions(+), 25 deletions(-) mode change 100755 => 100644 btif/include/btif_av.h mode change 100755 => 100644 btif/include/btif_common.h mode change 100644 => 100755 btif/src/btif_core.c mode change 100755 => 100644 conf/bt_did.conf diff --git a/btif/include/btif_av.h b/btif/include/btif_av.h old mode 100755 new mode 100644 diff --git a/btif/include/btif_common.h b/btif/include/btif_common.h old mode 100755 new mode 100644 diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c old mode 100644 new mode 100755 index 51328a8..d3c8447 --- a/btif/src/btif_core.c +++ b/btif/src/btif_core.c @@ -512,10 +512,10 @@ void btif_enable_bluetooth_evt(tBTA_STATUS status, BD_ADDR local_bd) /* init rfcomm & l2cap api */ btif_sock_init(); - - /* init pan */ + + /* init pan */ btif_pan_init(); - + /* load did configuration */ bte_load_did_conf(BTE_DID_CONF_FILE); diff --git a/btif/src/btif_media_task.c b/btif/src/btif_media_task.c index b0133a9..d3c267e 100755 --- a/btif/src/btif_media_task.c +++ b/btif/src/btif_media_task.c @@ -134,6 +134,11 @@ enum BTIF_MEDIA_AUDIO_RECEIVING_INIT }; +enum { + MEDIA_TASK_STATE_OFF = 0, + MEDIA_TASK_STATE_ON = 1, + MEDIA_TASK_STATE_SHUTTING_DOWN = 2 +}; /* Macro to multiply the media task tick */ #ifndef BTIF_MEDIA_NUM_TICK @@ -275,7 +280,7 @@ typedef struct { *****************************************************************************/ static tBTIF_MEDIA_CB btif_media_cb; -static int media_task_running = 0; +static int media_task_running = MEDIA_TASK_STATE_OFF; /***************************************************************************** @@ -473,6 +478,12 @@ static void btif_recv_ctrl_data(void) { case A2DP_CTRL_CMD_CHECK_READY: + if (media_task_running == MEDIA_TASK_STATE_SHUTTING_DOWN) + { + a2dp_cmd_acknowledge(A2DP_CTRL_ACK_FAILURE); + return; + } + /* check whether avdtp is ready to start */ if (btif_av_stream_ready() == TRUE) { @@ -547,8 +558,9 @@ static void btif_a2dp_ctrl_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event) break; case UIPC_CLOSE_EVT: - /* restart ctrl server */ - UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb); + /* restart ctrl server unless we are shutting down */ + if (media_task_running != MEDIA_TASK_STATE_SHUTTING_DOWN) + UIPC_Open(UIPC_CH_ID_AV_CTRL , btif_a2dp_ctrl_cb); break; case UIPC_RX_DATA_READY_EVT: @@ -573,12 +585,12 @@ static void btif_a2dp_data_cb(tUIPC_CH_ID ch_id, tUIPC_EVENT event) connection events */ UIPC_Ioctl(UIPC_CH_ID_AV_AUDIO, UIPC_REG_REMOVE_ACTIVE_READSET, NULL); - /* make sure we update any changed sbc encoder params */ - btif_a2dp_encoder_update(); - /* Start the media task to encode SBC */ btif_media_task_start_aa_req(); + /* make sure we update any changed sbc encoder params */ + btif_a2dp_encoder_update(); + /* ack back when media task is fully started */ break; @@ -700,7 +712,7 @@ int btif_a2dp_start_media_task(void) { int retval; - if (media_task_running) + if (media_task_running != MEDIA_TASK_STATE_OFF) { APPL_TRACE_ERROR0("warning : media task already running"); return GKI_FAILURE; @@ -718,7 +730,7 @@ int btif_a2dp_start_media_task(void) return retval; /* wait for task to come up to sure we are able to send messages to it */ - while (media_task_running == 0) + while (media_task_running == MEDIA_TASK_STATE_OFF) usleep(10); APPL_TRACE_EVENT0("## A2DP MEDIA TASK STARTED ##"); @@ -1183,7 +1195,7 @@ int btif_media_task(void *p) btif_media_task_init(); - media_task_running = 1; + media_task_running = MEDIA_TASK_STATE_ON; while (1) { @@ -1221,13 +1233,17 @@ int btif_media_task(void *p) /* When we get this event we exit the task - should only happen on GKI_shutdown */ if (event & BTIF_MEDIA_TASK_KILL) { + /* make sure no channels are restarted while shutting down */ + media_task_running = MEDIA_TASK_STATE_SHUTTING_DOWN; + + /* this calls blocks until uipc is fully closed */ UIPC_Close(UIPC_CH_ID_ALL); break; } } /* Clear media task flag */ - media_task_running = 0; + media_task_running = MEDIA_TASK_STATE_OFF; APPL_TRACE_DEBUG0("MEDIA TASK EXITING"); diff --git a/conf/bt_did.conf b/conf/bt_did.conf old mode 100755 new mode 100644 diff --git a/udrv/ulinux/uipc.c b/udrv/ulinux/uipc.c index 6440323..832afb3 100644 --- a/udrv/ulinux/uipc.c +++ b/udrv/ulinux/uipc.c @@ -239,7 +239,7 @@ static int accept_server_socket(int sfd) { struct sockaddr_un remote; int fd; - int t; + int t = sizeof(struct sockaddr); //BTIF_TRACE_EVENT1("accept fd %d", sfd); @@ -294,12 +294,14 @@ void uipc_main_cleanup(void) { int i; + BTIF_TRACE_EVENT0("uipc_main_cleanup"); + close(uipc_main.signal_fds[0]); close(uipc_main.signal_fds[1]); /* close any open channels */ for (i=0; i= UIPC_CH_NUM) return -1; - if (ch_id == UIPC_CH_ID_ALL) - { - /* shutdown read thread */ - uipc_main.running = 0; - uipc_wakeup_locked(); - return 0; - } - if (uipc_main.ch[ch_id].srvfd != UIPC_DISCONNECTED) { BTIF_TRACE_EVENT1("CLOSE SERVER (FD %d)", uipc_main.ch[ch_id].srvfd); @@ -577,9 +571,13 @@ static void uipc_read_task(void *arg) UIPC_UNLOCK(); } - BTIF_TRACE_EVENT0("UIPC READ THEAD EXITING"); + BTIF_TRACE_EVENT0("UIPC READ THREAD EXITING"); uipc_main_cleanup(); + + uipc_main.tid = 0; + + BTIF_TRACE_EVENT0("UIPC READ THREAD DONE"); } @@ -596,6 +594,20 @@ int uipc_start_main_server_thread(void) return 0; } +/* blocking call */ +void uipc_stop_main_server_thread(void) +{ + /* request shutdown of read thread */ + UIPC_LOCK(); + uipc_main.running = 0; + uipc_wakeup_locked(); + UIPC_UNLOCK(); + + /* wait until read thread is fully terminated */ + if (uipc_main.tid > 0) + pthread_join(uipc_main.tid, NULL); +} + /******************************************************************************* ** ** Function UIPC_Init @@ -678,6 +690,14 @@ UDRV_API void UIPC_Close(tUIPC_CH_ID ch_id) UIPC_LOCK(); uipc_close_locked(ch_id); UIPC_UNLOCK(); + + /* special case handling uipc shutdown */ + if (ch_id == UIPC_CH_ID_ALL) + { + BTIF_TRACE_DEBUG0("UIPC_Close : waiting for shutdown to complete"); + uipc_stop_main_server_thread(); + BTIF_TRACE_DEBUG0("UIPC_Close : shutdown complete"); + } } /******************************************************************************* @@ -785,7 +805,8 @@ UDRV_API UINT32 UIPC_Read(tUIPC_CH_ID ch_id, UINT16 *p_msg_evt, UINT8 *p_buf, UI pfd.fd = fd; pfd.events = POLLIN|POLLHUP; - /* make sure there is data prior to attempting read */ + /* make sure there is data prior to attempting read to avoid blocking + a read for more than poll timeout */ if (poll(&pfd, 1, uipc_main.ch[ch_id].read_poll_tmo_ms) == 0) { BTIF_TRACE_EVENT1("poll timeout (%d ms)", uipc_main.ch[ch_id].read_poll_tmo_ms); -- cgit v1.1