summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Agren <magren@broadcom.com>2012-04-19 23:10:53 +0200
committerMatthew Xie <mattx@google.com>2012-07-14 11:19:17 -0700
commit0872cc31abb3990b0892898f45bf2c87da627e4c (patch)
tree27f8f72cb243ddc93ba9f2eb4f254060619057fb
parente35926125a5320f5de50c22765f8ce07c588ff78 (diff)
downloadexternal_bluetooth_bluedroid-0872cc31abb3990b0892898f45bf2c87da627e4c.zip
external_bluetooth_bluedroid-0872cc31abb3990b0892898f45bf2c87da627e4c.tar.gz
external_bluetooth_bluedroid-0872cc31abb3990b0892898f45bf2c87da627e4c.tar.bz2
Ensure UIPC task is fully shutdown upon termination of btif media task.
Change-Id: Ie924cd324c85ca2037e94402a145a4eeeed62511
-rw-r--r--[-rwxr-xr-x]btif/include/btif_av.h0
-rw-r--r--[-rwxr-xr-x]btif/include/btif_common.h0
-rwxr-xr-x[-rw-r--r--]btif/src/btif_core.c6
-rwxr-xr-xbtif/src/btif_media_task.c36
-rw-r--r--[-rwxr-xr-x]conf/bt_did.conf0
-rw-r--r--udrv/ulinux/uipc.c45
6 files changed, 62 insertions, 25 deletions
diff --git a/btif/include/btif_av.h b/btif/include/btif_av.h
index e481459..e481459 100755..100644
--- a/btif/include/btif_av.h
+++ b/btif/include/btif_av.h
diff --git a/btif/include/btif_common.h b/btif/include/btif_common.h
index 3ecea9f..3ecea9f 100755..100644
--- a/btif/include/btif_common.h
+++ b/btif/include/btif_common.h
diff --git a/btif/src/btif_core.c b/btif/src/btif_core.c
index 51328a8..d3c8447 100644..100755
--- 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
index 2b88d5e..2b88d5e 100755..100644
--- a/conf/bt_did.conf
+++ b/conf/bt_did.conf
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; i++)
- UIPC_Close(i);
+ uipc_close_ch_locked(i);
}
@@ -480,14 +482,6 @@ static int uipc_close_ch_locked(tUIPC_CH_ID ch_id)
if (ch_id >= 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);