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 328702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt#define LOG_NDEBUG 0 338702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt 34fa644ffe944c01a9b00f8d7676d58394fabee285San MehatSocketListener::SocketListener(const char *socketName, bool listen) { 358702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt init(socketName, -1, listen, false); 36168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 37168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 38fa644ffe944c01a9b00f8d7676d58394fabee285San MehatSocketListener::SocketListener(int socketFd, bool listen) { 398702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt init(NULL, socketFd, listen, false); 408702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt} 418702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt 428702bb17f40022e970e8acd40b348d074e39afc7Robert GreenwaltSocketListener::SocketListener(const char *socketName, bool listen, bool useCmdNum) { 438702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt init(socketName, -1, listen, useCmdNum); 448702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt} 458702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt 468702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwaltvoid SocketListener::init(const char *socketName, int socketFd, bool listen, bool useCmdNum) { 47fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mListen = listen; 488702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mSocketName = socketName; 49168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSock = socketFd; 508702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mUseCmdNum = useCmdNum; 51fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_init(&mClientsLock, NULL); 52fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat mClients = new SocketClientCollection(); 53168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 54168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 55c4a895b7094461c98101924cf096680bfb7856f1San MehatSocketListener::~SocketListener() { 56c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (mSocketName && mSock > -1) 57c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mSock); 58c4a895b7094461c98101924cf096680bfb7856f1San Mehat 59c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (mCtrlPipe[0] != -1) { 60c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mCtrlPipe[0]); 61c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mCtrlPipe[1]); 62c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 63c4a895b7094461c98101924cf096680bfb7856f1San Mehat SocketClientCollection::iterator it; 64100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner for (it = mClients->begin(); it != mClients->end();) { 6513aa8ad44570bceef73115cea749b11f30888530Brad Fitzpatrick (*it)->decRef(); 66c4a895b7094461c98101924cf096680bfb7856f1San Mehat it = mClients->erase(it); 67c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 68c4a895b7094461c98101924cf096680bfb7856f1San Mehat delete mClients; 69c4a895b7094461c98101924cf096680bfb7856f1San Mehat} 70c4a895b7094461c98101924cf096680bfb7856f1San Mehat 71fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatint SocketListener::startListener() { 72168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 73168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if (!mSocketName && mSock == -1) { 747e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Failed to start unbound listener"); 75168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat errno = EINVAL; 76168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -1; 77168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } else if (mSocketName) { 78168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat if ((mSock = android_get_control_socket(mSocketName)) < 0) { 797e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Obtaining file descriptor socket '%s' failed: %s", 80168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat mSocketName, strerror(errno)); 81168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat return -1; 82168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 838702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt SLOGV("got mSock = %d for %s", mSock, mSocketName); 84168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 85168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 86fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mListen && listen(mSock, 4) < 0) { 877e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Unable to listen on socket (%s)", strerror(errno)); 88fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 89df6c1b91e3813886070f35929583c30cfaead918San Mehat } else if (!mListen) 908702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mClients->push_back(new SocketClient(mSock, false, mUseCmdNum)); 91168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 92c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (pipe(mCtrlPipe)) { 937e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("pipe failed (%s)", strerror(errno)); 94fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 95c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 96fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 97c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) { 987e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("pthread_create (%s)", strerror(errno)); 99fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 100c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 101fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 102fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return 0; 103fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 104fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 105fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatint SocketListener::stopListener() { 106fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat char c = 0; 107100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner int rc; 108fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 109100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner rc = TEMP_FAILURE_RETRY(write(mCtrlPipe[1], &c, 1)); 110100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (rc != 1) { 1117e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Error writing to control pipe (%s)", strerror(errno)); 112fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 113fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 114fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 115fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat void *ret; 116fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (pthread_join(mThread, &ret)) { 1177e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("Error joining to listener thread (%s)", strerror(errno)); 118fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return -1; 119fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 120dbdb0db516fa4935ff7b5c05914932099237d808San Mehat close(mCtrlPipe[0]); 121dbdb0db516fa4935ff7b5c05914932099237d808San Mehat close(mCtrlPipe[1]); 122c4a895b7094461c98101924cf096680bfb7856f1San Mehat mCtrlPipe[0] = -1; 123c4a895b7094461c98101924cf096680bfb7856f1San Mehat mCtrlPipe[1] = -1; 124c4a895b7094461c98101924cf096680bfb7856f1San Mehat 125c4a895b7094461c98101924cf096680bfb7856f1San Mehat if (mSocketName && mSock > -1) { 126c4a895b7094461c98101924cf096680bfb7856f1San Mehat close(mSock); 127c4a895b7094461c98101924cf096680bfb7856f1San Mehat mSock = -1; 128c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 129c4a895b7094461c98101924cf096680bfb7856f1San Mehat 130c4a895b7094461c98101924cf096680bfb7856f1San Mehat SocketClientCollection::iterator it; 131100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner for (it = mClients->begin(); it != mClients->end();) { 132c4a895b7094461c98101924cf096680bfb7856f1San Mehat delete (*it); 133c4a895b7094461c98101924cf096680bfb7856f1San Mehat it = mClients->erase(it); 134c4a895b7094461c98101924cf096680bfb7856f1San Mehat } 135fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return 0; 136fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 137fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 138fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatvoid *SocketListener::threadStart(void *obj) { 139fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketListener *me = reinterpret_cast<SocketListener *>(obj); 140fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 141fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat me->runListener(); 142fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_exit(NULL); 143fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat return NULL; 144fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 145fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 146fa644ffe944c01a9b00f8d7676d58394fabee285San Mehatvoid SocketListener::runListener() { 147fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 148100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner SocketClientCollection *pendingList = new SocketClientCollection(); 149100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner 150168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat while(1) { 151fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketClientCollection::iterator it; 152168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat fd_set read_fds; 153168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat int rc = 0; 154100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner int max = -1; 155fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 156168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat FD_ZERO(&read_fds); 157168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 158fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mListen) { 159168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat max = mSock; 160fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat FD_SET(mSock, &read_fds); 161168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 162168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 163fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat FD_SET(mCtrlPipe[0], &read_fds); 164fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mCtrlPipe[0] > max) 165fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat max = mCtrlPipe[0]; 166fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 167fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 168fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat for (it = mClients->begin(); it != mClients->end(); ++it) { 169100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner int fd = (*it)->getSocket(); 170100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner FD_SET(fd, &read_fds); 171100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (fd > max) 172100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner max = fd; 173fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 174fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 1758702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt SLOGV("mListen=%d, max=%d, mSocketName=%s", mListen, max, mSocketName); 176df6c1b91e3813886070f35929583c30cfaead918San Mehat if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) { 177100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (errno == EINTR) 178100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner continue; 1798702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt SLOGE("select failed (%s) mListen=%d, max=%d", strerror(errno), mListen, max); 180fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat sleep(1); 181168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat continue; 182df6c1b91e3813886070f35929583c30cfaead918San Mehat } else if (!rc) 183fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat continue; 184fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 185dbdb0db516fa4935ff7b5c05914932099237d808San Mehat if (FD_ISSET(mCtrlPipe[0], &read_fds)) 186fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat break; 187fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat if (mListen && FD_ISSET(mSock, &read_fds)) { 188fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat struct sockaddr addr; 189100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner socklen_t alen; 190fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat int c; 191fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 192100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner do { 193100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner alen = sizeof(addr); 194100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner c = accept(mSock, &addr, &alen); 1958702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt SLOGV("%s got %d from accept", mSocketName, c); 196100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner } while (c < 0 && errno == EINTR); 197100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (c < 0) { 1987e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGE("accept failed (%s)", strerror(errno)); 199fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat sleep(1); 200fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat continue; 201168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 202fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 2038702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mClients->push_back(new SocketClient(c, true, mUseCmdNum)); 204fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_unlock(&mClientsLock); 205fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 206fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 207100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Add all active clients to the pending list first */ 208100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pendingList->clear(); 209100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pthread_mutex_lock(&mClientsLock); 210100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner for (it = mClients->begin(); it != mClients->end(); ++it) { 211100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner int fd = (*it)->getSocket(); 212100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (FD_ISSET(fd, &read_fds)) { 213100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pendingList->push_back(*it); 214100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner } 215100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner } 216100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pthread_mutex_unlock(&mClientsLock); 217100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner 218100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Process the pending list, since it is owned by the thread, 219100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner * there is no need to lock it */ 220100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner while (!pendingList->empty()) { 221100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Pop the first item from the list */ 222100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner it = pendingList->begin(); 223100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner SocketClient* c = *it; 224100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pendingList->erase(it); 2258795007a4aedb0860f6e7b838984ba8104f2febcVernon Tang /* Process it, if false is returned and our sockets are 2268795007a4aedb0860f6e7b838984ba8104f2febcVernon Tang * connection-based, remove and destroy it */ 2278795007a4aedb0860f6e7b838984ba8104f2febcVernon Tang if (!onDataAvailable(c) && mListen) { 228100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner /* Remove the client from our array */ 2298702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt SLOGV("going to zap %d for %s", c->getSocket(), mSocketName); 230100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pthread_mutex_lock(&mClientsLock); 231100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner for (it = mClients->begin(); it != mClients->end(); ++it) { 232100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner if (*it == c) { 233100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner mClients->erase(it); 234100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner break; 235fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 236fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 237100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner pthread_mutex_unlock(&mClientsLock); 2384520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang /* Remove our reference to the client */ 2394520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang c->decRef(); 240168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 241100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner } 242168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat } 243100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner delete pendingList; 244168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat} 245168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat 246db017545796747115b8797f03e662b0f398a7c7bSan Mehatvoid SocketListener::sendBroadcast(int code, const char *msg, bool addErrno) { 247fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_lock(&mClientsLock); 248fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat SocketClientCollection::iterator i; 249fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 250fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat for (i = mClients->begin(); i != mClients->end(); ++i) { 2518702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt // broadcasts are unsolicited and should not include a cmd number 2528702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt if ((*i)->sendMsg(code, msg, addErrno, false)) { 253a8185a622e368d1957e18a3ee9d29d45eda12cfcGuang Zhu SLOGW("Error sending broadcast (%s)", strerror(errno)); 254a8185a622e368d1957e18a3ee9d29d45eda12cfcGuang Zhu } 255a8185a622e368d1957e18a3ee9d29d45eda12cfcGuang Zhu } 256a8185a622e368d1957e18a3ee9d29d45eda12cfcGuang Zhu pthread_mutex_unlock(&mClientsLock); 257a8185a622e368d1957e18a3ee9d29d45eda12cfcGuang Zhu} 258