16ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach/****************************************************************************** 266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * 36ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * Copyright (C) 2009-2012 Broadcom Corporation 466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * 56ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * Licensed under the Apache License, Version 2.0 (the "License"); 66ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * you may not use this file except in compliance with the License. 76ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * You may obtain a copy of the License at: 866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * 96ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * http://www.apache.org/licenses/LICENSE-2.0 1066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * 116ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * Unless required by applicable law or agreed to in writing, software 126ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * distributed under the License is distributed on an "AS IS" BASIS, 136ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 146ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * See the License for the specific language governing permissions and 156ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach * limitations under the License. 1666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * 176ef101187774e30ddba6b46bbedef549a42196adAndre Eisenbach ******************************************************************************/ 1866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 1966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani/************************************************************************************ 2066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * 2166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * Filename: btif_sock_thread.c 2266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * 2366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * Description: socket select thread 2466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * 2566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani * 2666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ***********************************************************************************/ 2766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 2866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <hardware/bluetooth.h> 2966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <hardware/bt_sock.h> 3066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 3166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani//bta_jv_co_rfc_data 3266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <stdio.h> 3366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <stdlib.h> 3466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <errno.h> 3566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <string.h> 3666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <sys/types.h> 3766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <sys/socket.h> 3866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <sys/un.h> 3966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <time.h> 4066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <fcntl.h> 4166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <unistd.h> 4266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <signal.h> 4366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <pthread.h> 4466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <ctype.h> 4566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 4666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <sys/select.h> 4766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <sys/poll.h> 4866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <cutils/sockets.h> 4954cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy#include <alloca.h> 5066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 5166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#define LOG_TAG "BTIF_SOCK" 5266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "btif_common.h" 5366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "btif_util.h" 5466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 5566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "bd.h" 5666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 5766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "bta_api.h" 5866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "btif_sock.h" 5966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "btif_sock_thread.h" 6066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include "btif_sock_util.h" 6166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 6266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#include <cutils/log.h> 63a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie#define asrt(s) if(!(s)) APPL_TRACE_ERROR3("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__) 6466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#define print_events(events) do { \ 65a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG1("print poll event:%x", events); \ 66a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie if (events & POLLIN) APPL_TRACE_DEBUG0( " POLLIN "); \ 67a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie if (events & POLLPRI) APPL_TRACE_DEBUG0( " POLLPRI "); \ 68a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie if (events & POLLOUT) APPL_TRACE_DEBUG0( " POLLOUT "); \ 69a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie if (events & POLLERR) APPL_TRACE_DEBUG0( " POLLERR "); \ 70a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie if (events & POLLHUP) APPL_TRACE_DEBUG0( " POLLHUP "); \ 71a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie if (events & POLLNVAL) APPL_TRACE_DEBUG0(" POLLNVAL "); \ 72a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie if (events & POLLRDHUP) APPL_TRACE_DEBUG0(" POLLRDHUP"); \ 7366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } while(0) 7466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 7566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#define MAX_THREAD 8 7666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#define MAX_POLL 64 7766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#define POLL_EXCEPTION_EVENTS (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL) 7866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#define IS_EXCEPTION(e) ((e) & POLL_EXCEPTION_EVENTS) 7966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#define IS_READ(e) ((e) & POLLIN) 8066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani#define IS_WRITE(e) ((e) & POLLOUT) 8166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani/*cmd executes in socket poll thread */ 8254cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy#define CMD_WAKEUP 1 8354cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy#define CMD_EXIT 2 8454cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy#define CMD_ADD_FD 3 8554cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy#define CMD_USER_PRIVATE 4 8666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 8766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanitypedef struct { 8866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani struct pollfd pfd; 8966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani uint32_t user_id; 9066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int type; 9166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int flags; 9266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} poll_slot_t; 9366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanitypedef struct { 9466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int cmd_fdr, cmd_fdw; 9566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int poll_count; 9666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani poll_slot_t ps[MAX_POLL]; 9766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int psi[MAX_POLL]; //index of poll slot 9866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani volatile pid_t thread_id; 9966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani btsock_signaled_cb callback; 10054cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy btsock_cmd_cb cmd_callback; 10166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int used; 10266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} thread_slot_t; 10366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic thread_slot_t ts[MAX_THREAD]; 10466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 10566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 10666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 10766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic void *sock_poll_thread(void *arg); 10866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline void close_cmd_fd(int h); 10966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 11066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id); 11166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 11266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic pthread_mutex_t thread_slot_lock; 11366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 11466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 11566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline void set_socket_blocking(int s, int blocking) 11666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 11766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int opts; 11866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani opts = fcntl(s, F_GETFL); 119a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie if (opts<0) APPL_TRACE_ERROR1("set blocking (%s)", strerror(errno)); 12066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(blocking) 12166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani opts &= ~O_NONBLOCK; 12266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani else opts |= O_NONBLOCK; 12366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani fcntl(s, F_SETFL, opts); 12466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 12566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 12666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline int create_server_socket(const char* name) 12766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 12866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int s = socket(AF_LOCAL, SOCK_STREAM, 0); 129a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG1("covert name to android abstract name:%s", name); 13066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) >= 0) 13166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 13266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(listen(s, 5) == 0) 13366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 134a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG2("listen to local socket:%s, fd:%d", name, s); 13566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return s; 13666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 137a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie else APPL_TRACE_ERROR3("listen to local socket:%s, fd:%d failed, errno:%d", name, s, errno); 13866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 139a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie else APPL_TRACE_ERROR3("create local socket:%s fd:%d, failed, errno:%d", name, s, errno); 14066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani close(s); 14166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return -1; 14266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 14366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline int connect_server_socket(const char* name) 14466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 14566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int s = socket(AF_LOCAL, SOCK_STREAM, 0); 14666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani set_socket_blocking(s, TRUE); 14766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(socket_local_client_connect(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) >= 0) 14866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 149a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG2("connected to local socket:%s, fd:%d", name, s); 15066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return s; 15166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 152a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie else APPL_TRACE_ERROR3("connect to local socket:%s, fd:%d failed, errno:%d", name, s, errno); 15366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani close(s); 15466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return -1; 15566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 15666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline int accept_server_socket(int s) 15766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 15866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani struct sockaddr_un client_address; 15966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani socklen_t clen; 16066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int fd = accept(s, (struct sockaddr*)&client_address, &clen); 161a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG2("accepted fd:%d for server fd:%d", fd, s); 16266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return fd; 16366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 16466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline pthread_t create_thread(void *(*start_routine)(void *), void * arg) 16566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 16666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pthread_attr_t thread_attr; 16766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pthread_attr_init(&thread_attr); 16866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE); 16966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pthread_t thread_id = -1; 17066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if( pthread_create(&thread_id, &thread_attr, start_routine, arg)!=0 ) 17166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 172a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR1("pthread_create : %s", strerror(errno)); 17366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return -1; 17466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 17566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return thread_id; 17666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 17766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic void init_poll(int cmd_fd); 17866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic int alloc_thread_slot() 17966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 18066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int i; 18166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //revserd order to save guard uninitialized access to 0 index 18266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani for(i = MAX_THREAD - 1; i >=0; i--) 1838e6e9356d5386501d5e0988ce23d0c9aaed31a64zzy { 184a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG2("ts[%d].used:%d", i, ts[i].used); 18566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(!ts[i].used) 1868e6e9356d5386501d5e0988ce23d0c9aaed31a64zzy { 1878e6e9356d5386501d5e0988ce23d0c9aaed31a64zzy ts[i].used = 1; 18866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return i; 1898e6e9356d5386501d5e0988ce23d0c9aaed31a64zzy } 1908e6e9356d5386501d5e0988ce23d0c9aaed31a64zzy } 191a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR0("execeeded max thread count"); 19266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return -1; 19366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 19466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic void free_thread_slot(int h) 19566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 19666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(0 <= h && h < MAX_THREAD) 19766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 19866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani close_cmd_fd(h); 19966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].used = 0; 20066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 201a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie else APPL_TRACE_ERROR1("invalid thread handle:%d", h); 20266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 20366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryaniint btsock_thread_init() 20466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 20554cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy static int initialized; 206a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG1("in initialized:%d", initialized); 20754cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy if(!initialized) 20866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 20954cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy initialized = 1; 21054cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy init_slot_lock(&thread_slot_lock); 21154cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy int h; 21254cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy for(h = 0; h < MAX_THREAD; h++) 21354cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy { 21454cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy ts[h].cmd_fdr = ts[h].cmd_fdw = -1; 21554cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy ts[h].used = 0; 21654cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy ts[h].thread_id = -1; 21754cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy ts[h].poll_count = 0; 21854cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy ts[h].callback = NULL; 21954cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy ts[h].cmd_callback = NULL; 22054cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy } 22166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 22266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return TRUE; 22366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 22454cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzyint btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback) 22566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 22666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int ret = FALSE; 22754cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy asrt(callback || cmd_callback); 22866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani lock_slot(&thread_slot_lock); 22966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int h = alloc_thread_slot(); 23066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani unlock_slot(&thread_slot_lock); 231a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG1("alloc_thread_slot ret:%d", h); 23266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(h >= 0) 23366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 23466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani init_poll(h); 23566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if((ts[h].thread_id = create_thread(sock_poll_thread, (void*)h)) != -1) 23666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 237a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG2("h:%d, thread id:%d", h, ts[h].thread_id); 23866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].callback = callback; 23954cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy ts[h].cmd_callback = cmd_callback; 24066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 24166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani else 24266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 24366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani free_thread_slot(h); 24466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani h = -1; 24566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 24666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 24766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return h; 24866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 24966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 25066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani/* create dummy socket pair used to wake up select loop */ 25166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline void init_cmd_fd(int h) 25266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 25366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani asrt(ts[h].cmd_fdr == -1 && ts[h].cmd_fdw == -1); 25466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(socketpair(AF_UNIX, SOCK_STREAM, 0, &ts[h].cmd_fdr) < 0) 25566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 256a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR1("socketpair failed: %s", strerror(errno)); 25766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return; 25866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 259a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG3("h:%d, cmd_fdr:%d, cmd_fdw:%d", h, ts[h].cmd_fdr, ts[h].cmd_fdw); 26066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //add the cmd fd for read & write 26166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani add_poll(h, ts[h].cmd_fdr, 0, SOCK_THREAD_FD_RD, 0); 26266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 26366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline void close_cmd_fd(int h) 26466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 26566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ts[h].cmd_fdr != -1) 26666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 26766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani close(ts[h].cmd_fdr); 26866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].cmd_fdr = -1; 26966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 27066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ts[h].cmd_fdw != -1) 27166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 27266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani close(ts[h].cmd_fdw); 27366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].cmd_fdw = -1; 27466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 27566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 27666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanitypedef struct 27766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 27866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int id; 27966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int fd; 28066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int type; 28166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int flags; 28266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani uint32_t user_id; 28366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} sock_cmd_t; 28466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryaniint btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id) 28566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 28666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(h < 0 || h >= MAX_THREAD) 28766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 288a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR1("invalid bt thread handle:%d", h); 28966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return FALSE; 29066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 29166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ts[h].cmd_fdw == -1) 29266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 293a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR0("cmd socket is not created. socket thread may not initialized"); 29466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return FALSE; 29566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 29666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(flags & SOCK_THREAD_ADD_FD_SYNC) 29766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 29866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //must executed in socket poll thread 2997f58927df0ee3f2f38367efe62c8901a760eeaa4zzy if(ts[h].thread_id == pthread_self()) 3007f58927df0ee3f2f38367efe62c8901a760eeaa4zzy { 3017f58927df0ee3f2f38367efe62c8901a760eeaa4zzy //cleanup one-time flags 3027f58927df0ee3f2f38367efe62c8901a760eeaa4zzy flags &= ~SOCK_THREAD_ADD_FD_SYNC; 3037f58927df0ee3f2f38367efe62c8901a760eeaa4zzy add_poll(h, fd, type, flags, user_id); 3047f58927df0ee3f2f38367efe62c8901a760eeaa4zzy return TRUE; 3057f58927df0ee3f2f38367efe62c8901a760eeaa4zzy } 306a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG0("THREAD_ADD_FD_SYNC is not called in poll thread, fallback to async"); 30766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 30866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani sock_cmd_t cmd = {CMD_ADD_FD, fd, type, flags, user_id}; 309a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG2("adding fd:%d, flags:0x%x", fd, flags); 31066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd); 31166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 31254cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzyint btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id) 31354cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy{ 31454cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy if(h < 0 || h >= MAX_THREAD) 31554cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy { 316a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR1("invalid bt thread handle:%d", h); 31754cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy return FALSE; 31854cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy } 31954cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy if(ts[h].cmd_fdw == -1) 32054cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy { 321a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR0("cmd socket is not created. socket thread may not initialized"); 32254cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy return FALSE; 32354cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy } 32454cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy sock_cmd_t cmd = {CMD_USER_PRIVATE, 0, type, size, user_id}; 325a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG3("post cmd type:%d, size:%d, h:%d, ", type, size, h); 32654cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy sock_cmd_t* cmd_send = &cmd; 32754cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy int size_send = sizeof(cmd); 32854cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy if(data && size) 32954cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy { 33054cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy size_send = sizeof(cmd) + size; 33154cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy cmd_send = (sock_cmd_t*)alloca(size_send); 33254cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy if(cmd_send) 33354cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy { 33454cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy *cmd_send = cmd; 33554cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy memcpy(cmd_send + 1, data, size); 33654cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy } 33754cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy else 33854cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy { 339a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR3("alloca failed at h:%d, cmd type:%d, size:%d", h, type, size_send); 34054cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy return FALSE; 34154cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy } 34254cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy } 34354cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy return send(ts[h].cmd_fdw, cmd_send, size_send, 0) == size_send; 34454cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy} 34566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryaniint btsock_thread_wakeup(int h) 34666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 34766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(h < 0 || h >= MAX_THREAD) 34866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 349a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR1("invalid bt thread handle:%d", h); 35066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return FALSE; 35166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 35266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ts[h].cmd_fdw == -1) 35366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 354a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR1("thread handle:%d, cmd socket is not created", h); 35566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return FALSE; 35666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 35766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani sock_cmd_t cmd = {CMD_WAKEUP, 0, 0, 0, 0}; 35866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd); 35966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 36066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryaniint btsock_thread_exit(int h) 36166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 36266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(h < 0 || h >= MAX_THREAD) 36366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 364a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR1("invalid bt thread handle:%d", h); 36566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return FALSE; 36666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 36766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ts[h].cmd_fdw == -1) 36866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 369a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR0("cmd socket is not created"); 37066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return FALSE; 37166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 37266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani sock_cmd_t cmd = {CMD_EXIT, 0, 0, 0, 0}; 37366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd)) 37466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 37566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pthread_join(ts[h].thread_id, 0); 37666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani lock_slot(&thread_slot_lock); 37766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani free_thread_slot(h); 37866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani unlock_slot(&thread_slot_lock); 37966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return TRUE; 38066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 38166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return FALSE; 38266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 38366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic void init_poll(int h) 38466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 38566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int i; 38666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].poll_count = 0; 38766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].thread_id = -1; 38866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].callback = NULL; 38954cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy ts[h].cmd_callback = NULL; 39066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani for(i = 0; i < MAX_POLL; i++) 39166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 39266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].ps[i].pfd.fd = -1; 39366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].psi[i] = -1; 39466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 39566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani init_cmd_fd(h); 39666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 39766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline unsigned int flags2pevents(int flags) 39866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 39966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani unsigned int pevents = 0; 40066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(flags & SOCK_THREAD_FD_WR) 40166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pevents |= POLLOUT; 40266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(flags & SOCK_THREAD_FD_RD) 40366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pevents |= POLLIN; 40466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pevents |= POLL_EXCEPTION_EVENTS; 40566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return pevents; 40666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 40766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 40866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline void set_poll(poll_slot_t* ps, int fd, int type, int flags, uint32_t user_id) 40966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 41066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps->pfd.fd = fd; 41166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps->user_id = user_id; 41266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ps->type != 0 && ps->type != type) 413a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR2("poll socket type should not changed! type was:%d, type now:%d", ps->type, type); 41466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps->type = type; 41566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps->flags = flags; 41666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps->pfd.events = flags2pevents(flags); 41766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps->pfd.revents = 0; 41866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 41966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id) 42066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 42166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani asrt(fd != -1); 42266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int i; 42366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int empty = -1; 42466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani poll_slot_t* ps = ts[h].ps; 42566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 42666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani for(i = 0; i < MAX_POLL; i++) 42766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 42866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ps[i].pfd.fd == fd) 42966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 43066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani asrt(ts[h].poll_count < MAX_POLL); 43166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 43266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani set_poll(&ps[i], fd, type, flags | ps[i].flags, user_id); 43366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return; 43466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 43566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani else if(empty < 0 && ps[i].pfd.fd == -1) 43666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani empty = i; 43766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 43866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(empty >= 0) 43966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 44066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani asrt(ts[h].poll_count < MAX_POLL); 44166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani set_poll(&ps[empty], fd, type, flags, user_id); 44266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ++ts[h].poll_count; 44366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return; 44466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 445a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR1("exceeded max poll slot:%d!", MAX_POLL); 44666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 44766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic inline void remove_poll(int h, poll_slot_t* ps, int flags) 44866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 44966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(flags == ps->flags) 45066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 45166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //all monitored events signaled. To remove it, just clear the slot 45266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani --ts[h].poll_count; 45366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani memset(ps, 0, sizeof(*ps)); 45466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps->pfd.fd = -1; 45566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 45666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani else 45766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 45866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //one read or one write monitor event signaled, removed the accordding bit 45966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps->flags &= ~flags; 46066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //update the poll events mask 46166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps->pfd.events = flags2pevents(ps->flags); 46266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 46366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 46466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic int process_cmd_sock(int h) 46566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 46666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani sock_cmd_t cmd = {-1, 0, 0, 0, 0}; 46766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int fd = ts[h].cmd_fdr; 46866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(recv(fd, &cmd, sizeof(cmd), MSG_WAITALL) != sizeof(cmd)) 46966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 470a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR1("recv cmd errno:%d", errno); 47166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return FALSE; 47266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 473a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG1("cmd.id:%d", cmd.id); 47466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani switch(cmd.id) 47566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 47666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani case CMD_ADD_FD: 47766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani add_poll(h, cmd.fd, cmd.type, cmd.flags, cmd.user_id); 47866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani break; 47966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani case CMD_WAKEUP: 48066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani break; 48154cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy case CMD_USER_PRIVATE: 48254cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy asrt(ts[h].cmd_callback); 48354cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy if(ts[h].cmd_callback) 48454cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy ts[h].cmd_callback(fd, cmd.type, cmd.flags, cmd.user_id); 48554cdfabe7c0ed98732d0641ffe8b19ff7284e7d4zzy break; 48666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani case CMD_EXIT: 48766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return FALSE; 48866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani default: 489a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG1("unknown cmd: %d", cmd.id); 49066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani break; 49166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 49266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return TRUE; 49366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 49466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic void process_data_sock(int h, struct pollfd *pfds, int count) 49566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 49666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani asrt(count <= ts[h].poll_count); 49766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int i; 49866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani for( i= 1; i < ts[h].poll_count; i++) 49966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 50066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(pfds[i].revents) 50166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 50266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int ps_i = ts[h].psi[i]; 50366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani asrt(pfds[i].fd == ts[h].ps[ps_i].pfd.fd); 50466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani uint32_t user_id = ts[h].ps[ps_i].user_id; 50566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int type = ts[h].ps[ps_i].type; 50666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int flags = 0; 50766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani print_events(pfds[i].revents); 50866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(IS_READ(pfds[i].revents)) 50966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 51066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani flags |= SOCK_THREAD_FD_RD; 51166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 51266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(IS_WRITE(pfds[i].revents)) 51366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 51466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani flags |= SOCK_THREAD_FD_WR; 51566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 51666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(IS_EXCEPTION(pfds[i].revents)) 51766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 51866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani flags |= SOCK_THREAD_FD_EXCEPTION; 51966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani //remove the whole slot not flags 52066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani remove_poll(h, &ts[h].ps[ps_i], ts[h].ps[ps_i].flags); 52166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 52266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani else if(flags) 52366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani remove_poll(h, &ts[h].ps[ps_i], flags); //remove the monitor flags that already processed 52466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(flags) 52566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].callback(pfds[i].fd, type, flags, user_id); 52666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 52766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 52866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 529a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie 53066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic void prepare_poll_fds(int h, struct pollfd* pfds) 53166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 53266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int count = 0; 53366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int ps_i = 0; 53466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int pfd_i = 0; 53566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani asrt(ts[h].poll_count <= MAX_POLL); 53666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani memset(pfds, 0, sizeof(pfds[0])*ts[h].poll_count); 53766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani while(count < ts[h].poll_count) 53866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 53966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ps_i >= MAX_POLL) 54066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 541a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR4("exceed max poll range, ps_i:%d, MAX_POLL:%d, count:%d, ts[h].poll_count:%d", 54266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps_i, MAX_POLL, count, ts[h].poll_count); 54366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return; 54466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 54566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ts[h].ps[ps_i].pfd.fd >= 0) 54666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 54766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pfds[pfd_i] = ts[h].ps[ps_i].pfd; 54866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].psi[pfd_i] = ps_i; 54966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani count++; 55066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani pfd_i++; 55166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 55266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ps_i++; 55366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 55466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 55566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryanistatic void *sock_poll_thread(void *arg) 55666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani{ 55766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani struct pollfd pfds[MAX_POLL]; 55866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani memset(pfds, 0, sizeof(pfds)); 55966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int h = (int)arg; 56066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani for(;;) 56166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 56266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani prepare_poll_fds(h, pfds); 56366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int ret = poll(pfds, ts[h].poll_count, -1); 56466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ret == -1) 56566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 566a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_ERROR2("poll ret -1, exit the thread, errno:%d, err:%s", errno, strerror(errno)); 56766aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani break; 56866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 56966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ret != 0) 57066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 57166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani int need_process_data_fd = TRUE; 57266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(pfds[0].revents) //cmd fd always is the first one 57366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 57466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani asrt(pfds[0].fd == ts[h].cmd_fdr); 57566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(!process_cmd_sock(h)) 57666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani { 577a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG1("h:%d, process_cmd_sock return false, exit...", h); 57866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani break; 57966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 58066aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(ret == 1) 58166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani need_process_data_fd = FALSE; 58266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani else ret--; //exclude the cmd fd 58366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 58466aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani if(need_process_data_fd) 58566aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani process_data_sock(h, pfds, ret); 58666aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 587a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie else {APPL_TRACE_DEBUG1("no data, select ret: %d", ret)}; 58866aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani } 58966aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani ts[h].thread_id = -1; 590a0d1575ab0b024b8198c27e69df6c9a0d55cbeeeMatthew Xie APPL_TRACE_DEBUG1("socket poll thread exiting, h:%d", h); 59166aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani return 0; 59266aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani} 59366aa5171e4e7c9f942971a30419c03134e67a4a4Harish Paryani 594