SocketListener.cpp revision 13aa8ad44570bceef73115cea749b11f30888530
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();) {
5813aa8ad44570bceef73115cea749b11f30888530Brad Fitzpatrick        (*it)->decRef();
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 */
22815d09854a8b2a1adf2fa5123ff77b9882afd6c22David 'Digit' Turner                close(c->getSocket());
22913aa8ad44570bceef73115cea749b11f30888530Brad Fitzpatrick                c->decRef();
230168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat            }
231100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner        }
232168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat    }
233100c0e2dab243da3a5351f1acbcdc560af10a405David 'Digit' Turner    delete pendingList;
234168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat}
235168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat
236db017545796747115b8797f03e662b0f398a7c7bSan Mehatvoid SocketListener::sendBroadcast(int code, const char *msg, bool addErrno) {
237fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    pthread_mutex_lock(&mClientsLock);
238fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    SocketClientCollection::iterator i;
239fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
240fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    for (i = mClients->begin(); i != mClients->end(); ++i) {
241d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat        if ((*i)->sendMsg(code, msg, addErrno)) {
2427e8529a8b528fd30586aa037f15a31b29582c537San Mehat            SLOGW("Error sending broadcast (%s)", strerror(errno));
243fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat        }
244fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    }
245fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    pthread_mutex_unlock(&mClientsLock);
246fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat}
247fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
248db017545796747115b8797f03e662b0f398a7c7bSan Mehatvoid SocketListener::sendBroadcast(const char *msg) {
249fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    pthread_mutex_lock(&mClientsLock);
250fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    SocketClientCollection::iterator i;
251fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat
252fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    for (i = mClients->begin(); i != mClients->end(); ++i) {
253d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat        if ((*i)->sendMsg(msg)) {
2547e8529a8b528fd30586aa037f15a31b29582c537San Mehat            SLOGW("Error sending broadcast (%s)", strerror(errno));
255fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat        }
256fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    }
257fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat    pthread_mutex_unlock(&mClientsLock);
258168415b822cae1f8b54ef09c41c11a9b97b87f40San Mehat}
259