SocketListener.cpp revision 100c0e2dab243da3a5351f1acbcdc560af10a405
1168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat/* 2168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Copyright (C) 2008 The Android Open Source Project 3168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 4168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * you may not use this file except in compliance with the License. 6168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * You may obtain a copy of the License at 7168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 8168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * 10168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * Unless required by applicable law or agreed to in writing, software 11168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * See the License for the specific language governing permissions and 14168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat * limitations under the License. 15168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat */ 16168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <stdio.h> 17168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <errno.h> 18168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <stdlib.h> 19168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/socket.h> 20168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/select.h> 21168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/time.h> 22168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/types.h> 23168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sys/un.h> 24168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 25168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#define LOG_TAG "SocketListener" 26168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <cutils/log.h> 27168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <cutils/sockets.h> 28168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 29168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat#include <sysutils/SocketListener.h> 30fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#include <sysutils/SocketClient.h> 31168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 32fa644ffe944c01a9b00f8d7676d58394fabee285San MehatSocketListener::SocketListener(const char *socketName, bool listen) { 33fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mListen = listen; 34168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName = socketName; 35168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSock = -1; 36fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_init(&mClientsLock, NULL); 37fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mClients = new SocketClientCollection(); 38168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 39168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 40fa644ffe944c01a9b00f8d7676d58394fabee285San MehatSocketListener::SocketListener(int socketFd, bool listen) { 41fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mListen = listen; 42168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName = NULL; 43168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSock = socketFd; 44fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_init(&mClientsLock, NULL); 45fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mClients = new SocketClientCollection(); 46168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 47168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 48c4a895b7094461c98101924cf096680bfb7856f1San MehatSocketListener::~SocketListener() { 49c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (mSocketName && mSock > -1) 50c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mSock); 51c4a895b7094461c98101924cf096680bfb7856f1San Mehat 52c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (mCtrlPipe[0] != -1) { 53c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mCtrlPipe[0]); 54c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mCtrlPipe[1]); 55c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 56c4a895b7094461c98101924cf096680bfb7856f1San Mehat SocketClientCollection::iterator it; 57100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner for (it = mClients->begin(); it != mClients->end();) { 58c4a895b7094461c98101924cf096680bfb7856f1San Mehat delete (*it); 59c4a895b7094461c98101924cf096680bfb7856f1San Mehat it = mClients->erase(it); 60c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 61c4a895b7094461c98101924cf096680bfb7856f1San Mehat delete mClients; 62c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 63c4a895b7094461c98101924cf096680bfb7856f1San Mehat 64fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatint SocketListener::startListener() { 65168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 66168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (!mSocketName && mSock == -1) { 677e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Failed to start unbound listener"); 68168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat errno = EINVAL; 69168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -1; 70168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } else if (mSocketName) { 71168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if ((mSock = android_get_control_socket(mSocketName)) < 0) { 727e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Obtaining file descriptor socket '%s' failed: %s", 73168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName, strerror(errno)); 74168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -1; 75168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 76168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 77168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 78fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mListen && listen(mSock, 4) < 0) { 797e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Unable to listen on socket (%s)", strerror(errno)); 80fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 81df6c1b91e3813886070f35929583c30cfaead918San Mehat } else if (!mListen) 82fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mClients->push_back(new SocketClient(mSock)); 83168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 84c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (pipe(mCtrlPipe)) { 857e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("pipe failed (%s)", strerror(errno)); 86fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 87c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 88fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 89c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) { 907e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("pthread_create (%s)", strerror(errno)); 91fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 92c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 93fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 94fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return 0; 95fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 96fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 97fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatint SocketListener::stopListener() { 98fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat char c = 0; 99100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner int rc; 100fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 101100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner rc = TEMP_FAILURE_RETRY(write(mCtrlPipe[1], &c, 1)); 102100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (rc != 1) { 1037e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Error writing to control pipe (%s)", strerror(errno)); 104fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 105fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 106fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 107fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat void *ret; 108fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (pthread_join(mThread, &ret)) { 1097e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Error joining to listener thread (%s)", strerror(errno)); 110fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 111fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 112dbdb0db516fa4935ff7b5c05914932099237d808San Mehat close(mCtrlPipe[0]); 113dbdb0db516fa4935ff7b5c05914932099237d808San Mehat close(mCtrlPipe[1]); 114c4a895b7094461c98101924cf096680bfb7856f1San Mehat mCtrlPipe[0] = -1; 115c4a895b7094461c98101924cf096680bfb7856f1San Mehat mCtrlPipe[1] = -1; 116c4a895b7094461c98101924cf096680bfb7856f1San Mehat 117c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (mSocketName && mSock > -1) { 118c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mSock); 119c4a895b7094461c98101924cf096680bfb7856f1San Mehat mSock = -1; 120c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 121c4a895b7094461c98101924cf096680bfb7856f1San Mehat 122c4a895b7094461c98101924cf096680bfb7856f1San Mehat SocketClientCollection::iterator it; 123100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner for (it = mClients->begin(); it != mClients->end();) { 124c4a895b7094461c98101924cf096680bfb7856f1San Mehat delete (*it); 125c4a895b7094461c98101924cf096680bfb7856f1San Mehat it = mClients->erase(it); 126c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 127fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return 0; 128fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 129fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 130fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatvoid *SocketListener::threadStart(void *obj) { 131fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketListener *me = reinterpret_cast<SocketListener *>(obj); 132fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 133fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat me->runListener(); 134fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_exit(NULL); 135fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return NULL; 136fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 137fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 138fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatvoid SocketListener::runListener() { 139fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 140100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner SocketClientCollection *pendingList = new SocketClientCollection(); 141100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner 142168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat while(1) { 143fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketClientCollection::iterator it; 144168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat fd_set read_fds; 145168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat int rc = 0; 146100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner int max = -1; 147fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 148168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat FD_ZERO(&read_fds); 149168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 150fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mListen) { 151168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat max = mSock; 152fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat FD_SET(mSock, &read_fds); 153168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 154168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 155fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat FD_SET(mCtrlPipe[0], &read_fds); 156fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mCtrlPipe[0] > max) 157fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat max = mCtrlPipe[0]; 158fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 159fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 160fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat for (it = mClients->begin(); it != mClients->end(); ++it) { 161100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner int fd = (*it)->getSocket(); 162100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner FD_SET(fd, &read_fds); 163100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (fd > max) 164100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner max = fd; 165fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 166fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 16703f0d27f6c49530a91402ed42f8ca4b2fda04b9fSan Mehat 168df6c1b91e3813886070f35929583c30cfaead918San Mehat if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) { 169100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (errno == EINTR) 170100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner continue; 1717e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("select failed (%s)", strerror(errno)); 172fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat sleep(1); 173168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat continue; 174df6c1b91e3813886070f35929583c30cfaead918San Mehat } else if (!rc) 175fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat continue; 176fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 177dbdb0db516fa4935ff7b5c05914932099237d808San Mehat if (FD_ISSET(mCtrlPipe[0], &read_fds)) 178fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat break; 179fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mListen && FD_ISSET(mSock, &read_fds)) { 180fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat struct sockaddr addr; 181100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner socklen_t alen; 182fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat int c; 183fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 184100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner do { 185100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner alen = sizeof(addr); 186100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner c = accept(mSock, &addr, &alen); 187100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner } while (c < 0 && errno == EINTR); 188100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (c < 0) { 1897e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("accept failed (%s)", strerror(errno)); 190fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat sleep(1); 191fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat continue; 192168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 193fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 194fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mClients->push_back(new SocketClient(c)); 195fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 196fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 197fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 198100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Add all active clients to the pending list first */ 199100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pendingList->clear(); 200100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pthread_mutex_lock(&mClientsLock); 201100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner for (it = mClients->begin(); it != mClients->end(); ++it) { 202100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner int fd = (*it)->getSocket(); 203100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (FD_ISSET(fd, &read_fds)) { 204100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pendingList->push_back(*it); 205100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner } 206100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner } 207100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pthread_mutex_unlock(&mClientsLock); 208100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner 209100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Process the pending list, since it is owned by the thread, 210100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner * there is no need to lock it */ 211100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner while (!pendingList->empty()) { 212100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Pop the first item from the list */ 213100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner it = pendingList->begin(); 214100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner SocketClient* c = *it; 215100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pendingList->erase(it); 216100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Process it, if false is returned, remove and destroy it */ 217100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (!onDataAvailable(c)) { 218100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Remove the client from our array */ 219100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pthread_mutex_lock(&mClientsLock); 220100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner for (it = mClients->begin(); it != mClients->end(); ++it) { 221100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (*it == c) { 222100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner mClients->erase(it); 223100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner break; 224fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 225fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 226100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pthread_mutex_unlock(&mClientsLock); 227100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Destroy the client */ 228100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner delete c; 229168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 230100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner } 231168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 232100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner delete pendingList; 233168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 234168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 235db017545796747115b8797f03e662b0f398a7c7bSan Mehatvoid SocketListener::sendBroadcast(int code, const char *msg, bool addErrno) { 236fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 237fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketClientCollection::iterator i; 238fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 239fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat for (i = mClients->begin(); i != mClients->end(); ++i) { 240d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat if ((*i)->sendMsg(code, msg, addErrno)) { 2417e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGW("Error sending broadcast (%s)", strerror(errno)); 242fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 243fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 244fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 245fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 246fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 247db017545796747115b8797f03e662b0f398a7c7bSan Mehatvoid SocketListener::sendBroadcast(const char *msg) { 248fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 249fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketClientCollection::iterator i; 250fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 251fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat for (i = mClients->begin(); i != mClients->end(); ++i) { 252d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat if ((*i)->sendMsg(msg)) { 2537e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGW("Error sending broadcast (%s)", strerror(errno)); 254fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 255fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 256fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 257168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 258