15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2009-2012 Broadcom Corporation 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at: 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License. 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/************************************************************************************ 205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Filename: btif_sock_thread.c 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Description: socket select thread 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ***********************************************************************************/ 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2849a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#define LOG_TAG "bt_btif_sock" 2949a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen 3049a86709488e5cfd5e23759da18bf9613e15b04dMarie Janssen#include "btif_sock_thread.h" 315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 32109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <alloca.h> 33109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <ctype.h> 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <errno.h> 35109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <fcntl.h> 36656c5a8c9ca254ce12f7acf4336fbc63998cc9e6Scott James Remnant#include <features.h> 37109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <pthread.h> 38109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <signal.h> 39109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <stdio.h> 40109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <stdlib.h> 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <string.h> 42109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <sys/poll.h> 43109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <sys/select.h> 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/socket.h> 45109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include <sys/types.h> 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <sys/un.h> 475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <time.h> 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <unistd.h> 495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bta_api.h" 51109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include "btif_common.h" 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock.h" 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_util.h" 54109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include "btif_util.h" 55109691281c0135fd4298debcdec37fdc5855261eMiao Chou#include "osi/include/socket_utils/sockets.h" 565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 57e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati#define asrt(s) if(!(s)) APPL_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__) 585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define print_events(events) do { \ 59e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("print poll event:%x", events); \ 60e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLIN) APPL_TRACE_DEBUG( " POLLIN "); \ 61e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLPRI) APPL_TRACE_DEBUG( " POLLPRI "); \ 62e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLOUT) APPL_TRACE_DEBUG( " POLLOUT "); \ 63e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLERR) APPL_TRACE_DEBUG( " POLLERR "); \ 64e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLHUP) APPL_TRACE_DEBUG( " POLLHUP "); \ 65e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLNVAL) APPL_TRACE_DEBUG(" POLLNVAL "); \ 66e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati if (events & POLLRDHUP) APPL_TRACE_DEBUG(" POLLRDHUP"); \ 675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } while(0) 685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define MAX_THREAD 8 705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define MAX_POLL 64 715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define POLL_EXCEPTION_EVENTS (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL) 725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define IS_EXCEPTION(e) ((e) & POLL_EXCEPTION_EVENTS) 735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define IS_READ(e) ((e) & POLLIN) 745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define IS_WRITE(e) ((e) & POLLOUT) 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/*cmd executes in socket poll thread */ 765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CMD_WAKEUP 1 775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CMD_EXIT 2 785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define CMD_ADD_FD 3 79f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans#define CMD_REMOVE_FD 4 80f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans#define CMD_USER_PRIVATE 5 815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct { 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct pollfd pfd; 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint32_t user_id; 855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int type; 865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int flags; 875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} poll_slot_t; 885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct { 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int cmd_fdr, cmd_fdw; 905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int poll_count; 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project poll_slot_t ps[MAX_POLL]; 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int psi[MAX_POLL]; //index of poll slot 93df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge volatile pthread_t thread_id; 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsock_signaled_cb callback; 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsock_cmd_cb cmd_callback; 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int used; 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} thread_slot_t; 985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic thread_slot_t ts[MAX_THREAD]; 995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void *sock_poll_thread(void *arg); 1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void close_cmd_fd(int h); 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id); 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1055381efce1f4fa20401df26b18b779e5b00cd5f1eIan Coolidgestatic pthread_mutex_t thread_slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 1065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 107df3459935a4c12744a9a78812157890b60ccb77dIan Coolidgestatic inline int create_thread(void *(*start_routine)(void *), void * arg, 108df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge pthread_t * thread_id) 1095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_attr_t thread_attr; 1115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_attr_init(&thread_attr); 1125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); 1138372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz int policy; 1148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz int min_pri=0; 1158372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz int ret = -1; 1168372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz struct sched_param param; 117aba88aee024266b4b8375d9b27b94469f15c2716Ian Coolidge 1188372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz if ((ret = pthread_create(thread_id, &thread_attr, start_routine, arg))!=0 ) 1198372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz { 1208372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz APPL_TRACE_ERROR("pthread_create : %s", strerror(errno)); 1218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz return ret; 1228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz } 1238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz /* We need to lower the priority of this thread to ensure the stack gets 1248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz * priority over transfer to a socket */ 1258372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz pthread_getschedparam(*thread_id, &policy, ¶m); 1268372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz min_pri = sched_get_priority_min(policy); 1278372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz if (param.sched_priority > min_pri) { 1288372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz param.sched_priority -= 1; 1298372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz } 1308372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz pthread_setschedparam(*thread_id, policy, ¶m); 1318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz return ret; 1328372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz} 1335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void init_poll(int cmd_fd); 1345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int alloc_thread_slot() 1355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 1375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //revserd order to save guard uninitialized access to 0 index 1385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(i = MAX_THREAD - 1; i >=0; i--) 1395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 140e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("ts[%d].used:%d", i, ts[i].used); 1415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(!ts[i].used) 1425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[i].used = 1; 1445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return i; 1455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 147e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("execeeded max thread count"); 1485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return -1; 1495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void free_thread_slot(int h) 1515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(0 <= h && h < MAX_THREAD) 1535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close_cmd_fd(h); 1555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].used = 0; 1565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 157e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati else APPL_TRACE_ERROR("invalid thread handle:%d", h); 1585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_init() 1605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project static int initialized; 162e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("in initialized:%d", initialized); 1635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(!initialized) 1645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project initialized = 1; 1665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int h; 1675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(h = 0; h < MAX_THREAD; h++) 1685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_fdr = ts[h].cmd_fdw = -1; 1705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].used = 0; 1715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].thread_id = -1; 1725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].poll_count = 0; 1735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].callback = NULL; 1745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_callback = NULL; 1755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 1775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 1785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback) 1805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 1815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(callback || cmd_callback); 1825381efce1f4fa20401df26b18b779e5b00cd5f1eIan Coolidge pthread_mutex_lock(&thread_slot_lock); 1835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int h = alloc_thread_slot(); 1845381efce1f4fa20401df26b18b779e5b00cd5f1eIan Coolidge pthread_mutex_unlock(&thread_slot_lock); 185e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("alloc_thread_slot ret:%d", h); 1865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h >= 0) 1875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 1885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project init_poll(h); 189df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge pthread_t thread; 190df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge int status = create_thread(sock_poll_thread, (void*)(uintptr_t)h, &thread); 191df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge if (status) 1925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 193df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge APPL_TRACE_ERROR("create_thread failed: %s", strerror(status)); 1945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project free_thread_slot(h); 195df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge return -1; 1965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 197df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge 198df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge ts[h].thread_id = thread; 199df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge APPL_TRACE_DEBUG("h:%d, thread id:%d", h, ts[h].thread_id); 200df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge ts[h].callback = callback; 201df3459935a4c12744a9a78812157890b60ccb77dIan Coolidge ts[h].cmd_callback = cmd_callback; 2025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return h; 2045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 2065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* create dummy socket pair used to wake up select loop */ 2075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void init_cmd_fd(int h) 2085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].cmd_fdr == -1 && ts[h].cmd_fdw == -1); 2105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(socketpair(AF_UNIX, SOCK_STREAM, 0, &ts[h].cmd_fdr) < 0) 2115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 212e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("socketpair failed: %s", strerror(errno)); 2135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 2145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 215e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("h:%d, cmd_fdr:%d, cmd_fdw:%d", h, ts[h].cmd_fdr, ts[h].cmd_fdw); 2165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //add the cmd fd for read & write 2175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project add_poll(h, ts[h].cmd_fdr, 0, SOCK_THREAD_FD_RD, 0); 2185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void close_cmd_fd(int h) 2205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdr != -1) 2225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close(ts[h].cmd_fdr); 2245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_fdr = -1; 2255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw != -1) 2275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project close(ts[h].cmd_fdw); 2295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_fdw = -1; 2305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct 2335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int id; 2355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int fd; 2365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int type; 2375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int flags; 2385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint32_t user_id; 2395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} sock_cmd_t; 2405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id) 2415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h < 0 || h >= MAX_THREAD) 2435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 244e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("invalid bt thread handle:%d", h); 2455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw == -1) 2485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 249e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("cmd socket is not created. socket thread may not initialized"); 2505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 2515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags & SOCK_THREAD_ADD_FD_SYNC) 2535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //must executed in socket poll thread 2555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].thread_id == pthread_self()) 2565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 2575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //cleanup one-time flags 2585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project flags &= ~SOCK_THREAD_ADD_FD_SYNC; 2595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project add_poll(h, fd, type, flags, user_id); 2605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 2615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 262e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("THREAD_ADD_FD_SYNC is not called in poll thread, fallback to async"); 2635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 2645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id}; 265e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("adding fd:%d, flags:0x%x", fd, flags); 266574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 267574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov ssize_t ret; 268574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov OSI_NO_INTR(ret = send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)); 269574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 270574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov return ret == sizeof(cmd); 2715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 272f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans 273f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gansbool btsock_thread_remove_fd_and_close(int thread_handle, int fd) 274f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans{ 275f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans if (thread_handle < 0 || thread_handle >= MAX_THREAD) 276f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans { 277f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans APPL_TRACE_ERROR("%s invalid thread handle: %d", __func__, thread_handle); 278f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans return false; 279f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans } 280f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans if (fd == -1) 281f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans { 282f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans APPL_TRACE_ERROR("%s invalid file descriptor.", __func__); 283f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans return false; 284f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans } 285f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans 286f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans sock_cmd_t cmd = {CMD_REMOVE_FD, fd, 0, 0, 0}; 287574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 288574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov ssize_t ret; 289574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov OSI_NO_INTR(ret = send(ts[thread_handle].cmd_fdw, &cmd, sizeof(cmd), 0)); 290574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 291574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov return ret == sizeof(cmd); 292f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans} 293f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans 2945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id) 2955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 2965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h < 0 || h >= MAX_THREAD) 2975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 298e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("invalid bt thread handle:%d", h); 2995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw == -1) 3025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 303e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("cmd socket is not created. socket thread may not initialized"); 3045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {CMD_USER_PRIVATE, 0, type, size, user_id}; 307e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("post cmd type:%d, size:%d, h:%d, ", type, size, h); 3085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t* cmd_send = &cmd; 3095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int size_send = sizeof(cmd); 3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(data && size) 3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project size_send = sizeof(cmd) + size; 3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project cmd_send = (sock_cmd_t*)alloca(size_send); 3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(cmd_send) 3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project *cmd_send = cmd; 3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memcpy(cmd_send + 1, data, size); 3185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 321e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("alloca failed at h:%d, cmd type:%d, size:%d", h, type, size_send); 3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 325574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 326574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov ssize_t ret; 327574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov OSI_NO_INTR(ret = send(ts[h].cmd_fdw, cmd_send, size_send, 0)); 328574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 329574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov return ret == size_send; 3305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_wakeup(int h) 3325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h < 0 || h >= MAX_THREAD) 3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 335e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("invalid bt thread handle:%d", h); 3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw == -1) 3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 340e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("thread handle:%d, cmd socket is not created", h); 3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {CMD_WAKEUP, 0, 0, 0, 0}; 344574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 345574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov ssize_t ret; 346574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov OSI_NO_INTR(ret = send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)); 347574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 348574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov return ret == sizeof(cmd); 3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectint btsock_thread_exit(int h) 3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(h < 0 || h >= MAX_THREAD) 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 354e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("invalid bt thread handle:%d", h); 3555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_fdw == -1) 3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 359e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("cmd socket is not created"); 3605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {CMD_EXIT, 0, 0, 0, 0}; 363574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 364574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov ssize_t ret; 365574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov OSI_NO_INTR(ret = send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0)); 366574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 367574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov if (ret == sizeof(cmd)) { 3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pthread_join(ts[h].thread_id, 0); 3695381efce1f4fa20401df26b18b779e5b00cd5f1eIan Coolidge pthread_mutex_lock(&thread_slot_lock); 3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project free_thread_slot(h); 3715381efce1f4fa20401df26b18b779e5b00cd5f1eIan Coolidge pthread_mutex_unlock(&thread_slot_lock); 3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void init_poll(int h) 3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].poll_count = 0; 3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].thread_id = -1; 3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].callback = NULL; 3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_callback = NULL; 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(i = 0; i < MAX_POLL; i++) 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].ps[i].pfd.fd = -1; 3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].psi[i] = -1; 3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project init_cmd_fd(h); 3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline unsigned int flags2pevents(int flags) 3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project unsigned int pevents = 0; 3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags & SOCK_THREAD_FD_WR) 3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pevents |= POLLOUT; 3955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags & SOCK_THREAD_FD_RD) 3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pevents |= POLLIN; 3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pevents |= POLL_EXCEPTION_EVENTS; 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return pevents; 3995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void set_poll(poll_slot_t* ps, int fd, int type, int flags, uint32_t user_id) 4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.fd = fd; 4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->user_id = user_id; 4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ps->type != 0 && ps->type != type) 406e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("poll socket type should not changed! type was:%d, type now:%d", ps->type, type); 4075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->type = type; 4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->flags = flags; 4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.events = flags2pevents(flags); 4105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.revents = 0; 4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id) 4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(fd != -1); 4155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 4165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int empty = -1; 4175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project poll_slot_t* ps = ts[h].ps; 4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(i = 0; i < MAX_POLL; i++) 4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ps[i].pfd.fd == fd) 4225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].poll_count < MAX_POLL); 4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project set_poll(&ps[i], fd, type, flags | ps[i].flags, user_id); 4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 4275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if(empty < 0 && ps[i].pfd.fd == -1) 4295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project empty = i; 4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(empty >= 0) 4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].poll_count < MAX_POLL); 4345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project set_poll(&ps[empty], fd, type, flags, user_id); 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ++ts[h].poll_count; 4365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 4375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 438e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("exceeded max poll slot:%d!", MAX_POLL); 4395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic inline void remove_poll(int h, poll_slot_t* ps, int flags) 4415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags == ps->flags) 4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //all monitored events signaled. To remove it, just clear the slot 4455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project --ts[h].poll_count; 4465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset(ps, 0, sizeof(*ps)); 4475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.fd = -1; 4485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else 4505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //one read or one write monitor event signaled, removed the accordding bit 4525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->flags &= ~flags; 4535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //update the poll events mask 4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps->pfd.events = flags2pevents(ps->flags); 4555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 4565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int process_cmd_sock(int h) 4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sock_cmd_t cmd = {-1, 0, 0, 0, 0}; 4605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int fd = ts[h].cmd_fdr; 461574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 462574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov ssize_t ret; 463574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov OSI_NO_INTR(ret = recv(fd, &cmd, sizeof(cmd), MSG_WAITALL)); 464574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov 465574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov if (ret != sizeof(cmd)) 4665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 467e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("recv cmd errno:%d", errno); 4685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 4695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 470e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("cmd.id:%d", cmd.id); 4715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project switch(cmd.id) 4725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 4735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case CMD_ADD_FD: 4745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project add_poll(h, cmd.fd, cmd.type, cmd.flags, cmd.user_id); 4755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 476f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans case CMD_REMOVE_FD: 477f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans for (int i = 1; i < MAX_POLL; ++i) 478f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans { 479f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans poll_slot_t *poll_slot = &ts[h].ps[i]; 480f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans if (poll_slot->pfd.fd == cmd.fd) 481f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans { 482f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans remove_poll(h, poll_slot, poll_slot->flags); 483f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans break; 484f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans } 485f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans } 486f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans close(cmd.fd); 487f866204ea74d594ba209522eebb7d1e5469ba7b0June R. Tate-Gans break; 4885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case CMD_WAKEUP: 4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case CMD_USER_PRIVATE: 4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].cmd_callback); 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].cmd_callback) 4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].cmd_callback(fd, cmd.type, cmd.flags, cmd.user_id); 4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 4955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case CMD_EXIT: 4965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return FALSE; 4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project default: 498e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("unknown cmd: %d", cmd.id); 4995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 5005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return TRUE; 5025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void process_data_sock(int h, struct pollfd *pfds, int count) 5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(count <= ts[h].poll_count); 5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int i; 5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for( i= 1; i < ts[h].poll_count; i++) 5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(pfds[i].revents) 5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ps_i = ts[h].psi[i]; 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(pfds[i].fd == ts[h].ps[ps_i].pfd.fd); 5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project uint32_t user_id = ts[h].ps[ps_i].user_id; 5145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int type = ts[h].ps[ps_i].type; 5155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int flags = 0; 5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project print_events(pfds[i].revents); 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(IS_READ(pfds[i].revents)) 5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project flags |= SOCK_THREAD_FD_RD; 5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(IS_WRITE(pfds[i].revents)) 5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project flags |= SOCK_THREAD_FD_WR; 5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(IS_EXCEPTION(pfds[i].revents)) 5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project flags |= SOCK_THREAD_FD_EXCEPTION; 5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project //remove the whole slot not flags 5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project remove_poll(h, &ts[h].ps[ps_i], ts[h].ps[ps_i].flags); 5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else if(flags) 5325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project remove_poll(h, &ts[h].ps[ps_i], flags); //remove the monitor flags that already processed 5335738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(flags) 5345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].callback(pfds[i].fd, type, flags, user_id); 5355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void prepare_poll_fds(int h, struct pollfd* pfds) 5405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int count = 0; 5425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int ps_i = 0; 5435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int pfd_i = 0; 5445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(ts[h].poll_count <= MAX_POLL); 5455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset(pfds, 0, sizeof(pfds[0])*ts[h].poll_count); 5465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project while(count < ts[h].poll_count) 5475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ps_i >= MAX_POLL) 5495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 550e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("exceed max poll range, ps_i:%d, MAX_POLL:%d, count:%d, ts[h].poll_count:%d", 5515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps_i, MAX_POLL, count, ts[h].poll_count); 5525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return; 5535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ts[h].ps[ps_i].pfd.fd >= 0) 5555738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pfds[pfd_i] = ts[h].ps[ps_i].pfd; 5575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].psi[pfd_i] = ps_i; 5585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project count++; 5595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pfd_i++; 5605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ps_i++; 5625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void *sock_poll_thread(void *arg) 5655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project struct pollfd pfds[MAX_POLL]; 5675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project memset(pfds, 0, sizeof(pfds)); 56822c6e505dc65ab3d624e4ccd7c48c95fe2128703Kévin PETIT int h = (intptr_t)arg; 5695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project for(;;) 5705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project prepare_poll_fds(h, pfds); 572574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov int ret; 573574dcfb73e3741d715f7d4394fe5d3bd587cb0d2Pavlin Radoslavov OSI_NO_INTR(ret = poll(pfds, ts[h].poll_count, -1)); 5745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ret == -1) 5755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 576e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_ERROR("poll ret -1, exit the thread, errno:%d, err:%s", errno, strerror(errno)); 5775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 5785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ret != 0) 5805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int need_process_data_fd = TRUE; 5825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(pfds[0].revents) //cmd fd always is the first one 5835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 5845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project asrt(pfds[0].fd == ts[h].cmd_fdr); 5855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(!process_cmd_sock(h)) 5865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 587e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("h:%d, process_cmd_sock return false, exit...", h); 5885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 5895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(ret == 1) 5915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project need_process_data_fd = FALSE; 5925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project else ret--; //exclude the cmd fd 5935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if(need_process_data_fd) 5955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project process_data_sock(h, pfds, ret); 5965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 597e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati else {APPL_TRACE_DEBUG("no data, select ret: %d", ret)}; 5985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 5995738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ts[h].thread_id = -1; 600e8c3d75b75493911ebf0f99c83676359657178f7Sharvil Nanavati APPL_TRACE_DEBUG("socket poll thread exiting, h:%d", h); 6015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return 0; 6025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 603