libsysutils: Add multiple client support and fix some bugs
This commit is contained in:
parent
1441e769b2
commit
fa644ffe94
15 changed files with 314 additions and 197 deletions
21
include/sysutils/FrameworkClient.h
Normal file
21
include/sysutils/FrameworkClient.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef _FRAMEWORK_CLIENT_H
|
||||
#define _FRAMEWORK_CLIENT_H
|
||||
|
||||
#include "../../../frameworks/base/include/utils/List.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
class FrameworkClient {
|
||||
int mSocket;
|
||||
pthread_mutex_t mWriteMutex;
|
||||
|
||||
public:
|
||||
FrameworkClient(int sock);
|
||||
virtual ~FrameworkClient() {}
|
||||
|
||||
int sendMsg(char *msg);
|
||||
int sendMsg(char *msg, char *data);
|
||||
};
|
||||
|
||||
typedef android::List<FrameworkClient *> FrameworkClientCollection;
|
||||
#endif
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "../../../frameworks/base/include/utils/List.h"
|
||||
|
||||
class SocketClient;
|
||||
|
||||
class FrameworkCommand {
|
||||
private:
|
||||
|
|
@ -28,7 +29,7 @@ public:
|
|||
FrameworkCommand(const char *cmd);
|
||||
virtual ~FrameworkCommand() { }
|
||||
|
||||
virtual int runCommand(char *data);
|
||||
virtual int runCommand(SocketClient *c, char *data) = 0;
|
||||
|
||||
const char *getCommand() { return mCommand; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include "SocketListener.h"
|
||||
#include "FrameworkCommand.h"
|
||||
|
||||
class SocketClient;
|
||||
|
||||
class FrameworkListener : public SocketListener {
|
||||
private:
|
||||
FrameworkCommandCollection *mCommands;
|
||||
|
|
@ -29,9 +31,9 @@ public:
|
|||
|
||||
protected:
|
||||
void registerCmd(FrameworkCommand *cmd);
|
||||
virtual bool onDataAvailable(int socket);
|
||||
virtual bool onDataAvailable(SocketClient *c);
|
||||
|
||||
private:
|
||||
void dispatchCommand(char *cmd);
|
||||
void dispatchCommand(SocketClient *c, char *cmd);
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef _FRAMEWORKMANAGER_H
|
||||
#define _FRAMEWORKMANAGER_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
class FrameworkListener;
|
||||
|
||||
class FrameworkManager {
|
||||
int mDoorbell; // Socket used to accept connections from framework
|
||||
int mFwSock; // Socket used to communicate with framework
|
||||
const char *mSocketName;
|
||||
|
||||
FrameworkListener *mListener;
|
||||
|
||||
pthread_mutex_t mWriteMutex;
|
||||
|
||||
public:
|
||||
FrameworkManager(FrameworkListener *Listener);
|
||||
virtual ~FrameworkManager() {}
|
||||
|
||||
int run();
|
||||
int sendMsg(char *msg);
|
||||
int sendMsg(char *msg, char *data);
|
||||
};
|
||||
#endif
|
||||
|
|
@ -27,6 +27,6 @@ public:
|
|||
NetlinkListener(int socket);
|
||||
virtual ~NetlinkListener() {}
|
||||
protected:
|
||||
virtual bool onDataAvailable(int socket);
|
||||
virtual bool onDataAvailable(SocketClient *cli);
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
23
include/sysutils/SocketClient.h
Normal file
23
include/sysutils/SocketClient.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _SOCKET_CLIENT_H
|
||||
#define _SOCKET_CLIENT_H
|
||||
|
||||
#include "../../../frameworks/base/include/utils/List.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
class SocketClient {
|
||||
int mSocket;
|
||||
pthread_mutex_t mWriteMutex;
|
||||
|
||||
public:
|
||||
SocketClient(int sock);
|
||||
virtual ~SocketClient() {}
|
||||
|
||||
int getSocket() { return mSocket; }
|
||||
|
||||
int sendMsg(char *msg);
|
||||
int sendMsg(char *msg, char *data);
|
||||
};
|
||||
|
||||
typedef android::List<SocketClient *> SocketClientCollection;
|
||||
#endif
|
||||
|
|
@ -16,20 +16,35 @@
|
|||
#ifndef _SOCKETLISTENER_H
|
||||
#define _SOCKETLISTENER_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sysutils/SocketClient.h>
|
||||
|
||||
class SocketListener {
|
||||
int mSock;
|
||||
int mCsock;
|
||||
int mAcceptClients;
|
||||
const char *mSocketName;
|
||||
int mSock;
|
||||
const char *mSocketName;
|
||||
SocketClientCollection *mClients;
|
||||
pthread_mutex_t mClientsLock;
|
||||
bool mListen;
|
||||
int mCtrlPipe[2];
|
||||
pthread_t mThread;
|
||||
|
||||
public:
|
||||
SocketListener(const char *socketName, bool acceptClients);
|
||||
SocketListener(int socketFd, bool acceptClients);
|
||||
SocketListener(const char *socketNames, bool listen);
|
||||
SocketListener(int socketFd, bool listen);
|
||||
|
||||
virtual ~SocketListener() {}
|
||||
virtual int run();
|
||||
int startListener();
|
||||
int stopListener();
|
||||
|
||||
void sendBroadcast(char *msg);
|
||||
void sendBroadcast(char *msg, char *data);
|
||||
|
||||
protected:
|
||||
virtual bool onDataAvailable(int socket);
|
||||
virtual bool onDataAvailable(SocketClient *c) = 0;
|
||||
|
||||
private:
|
||||
static void *threadStart(void *obj);
|
||||
void runListener();
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ LOCAL_PATH:= $(call my-dir)
|
|||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
src/FrameworkManager.cpp \
|
||||
src/SocketListener.cpp \
|
||||
src/FrameworkListener.cpp \
|
||||
src/NetlinkListener.cpp \
|
||||
src/NetlinkEvent.cpp \
|
||||
src/FrameworkCommand.cpp \
|
||||
src/SocketClient.cpp \
|
||||
|
||||
LOCAL_MODULE:= libsysutils
|
||||
|
||||
|
|
|
|||
41
libsysutils/src/FrameworkClient.cpp
Normal file
41
libsysutils/src/FrameworkClient.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include <alloca.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define LOG_TAG "FrameworkClient"
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <sysutils/FrameworkClient.h>
|
||||
|
||||
FrameworkClient::FrameworkClient(int socket) {
|
||||
mSocket = socket;
|
||||
pthread_mutex_init(&mWriteMutex, NULL);
|
||||
}
|
||||
|
||||
int FrameworkClient::sendMsg(char *msg) {
|
||||
LOGD("FrameworkClient::sendMsg(%s)", msg);
|
||||
if (mSocket < 0) {
|
||||
errno = EHOSTUNREACH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mWriteMutex);
|
||||
if (write(mSocket, msg, strlen(msg) +1) < 0) {
|
||||
LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno));
|
||||
}
|
||||
pthread_mutex_unlock(&mWriteMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FrameworkClient::sendMsg(char *msg, char *data) {
|
||||
char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1);
|
||||
if (!buffer) {
|
||||
errno = -ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
strcpy(buffer, msg);
|
||||
strcat(buffer, data);
|
||||
return sendMsg(buffer);
|
||||
}
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ FrameworkCommand::FrameworkCommand(const char *cmd) {
|
|||
mCommand = cmd;
|
||||
}
|
||||
|
||||
int FrameworkCommand::runCommand(char *data) {
|
||||
int FrameworkCommand::runCommand(SocketClient *c, char *data) {
|
||||
LOGW("Command %s has no run handler!", getCommand());
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -22,17 +22,18 @@
|
|||
|
||||
#include <sysutils/FrameworkListener.h>
|
||||
#include <sysutils/FrameworkCommand.h>
|
||||
#include <sysutils/SocketClient.h>
|
||||
|
||||
FrameworkListener::FrameworkListener(const char *socketName) :
|
||||
SocketListener(socketName, true) {
|
||||
mCommands = new FrameworkCommandCollection();
|
||||
}
|
||||
|
||||
bool FrameworkListener::onDataAvailable(int socket) {
|
||||
bool FrameworkListener::onDataAvailable(SocketClient *c) {
|
||||
char buffer[101];
|
||||
int len;
|
||||
|
||||
if ((len = read(socket, buffer, sizeof(buffer) -1)) < 0) {
|
||||
if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) {
|
||||
LOGE("read() failed (%s)", strerror(errno));
|
||||
return errno;
|
||||
} else if (!len) {
|
||||
|
|
@ -47,7 +48,7 @@ bool FrameworkListener::onDataAvailable(int socket) {
|
|||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (buffer[i] == '\0') {
|
||||
dispatchCommand(buffer + start);
|
||||
dispatchCommand(c, buffer + start);
|
||||
start = i + 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -58,14 +59,22 @@ void FrameworkListener::registerCmd(FrameworkCommand *cmd) {
|
|||
mCommands->push_back(cmd);
|
||||
}
|
||||
|
||||
void FrameworkListener::dispatchCommand(char *cmd) {
|
||||
void FrameworkListener::dispatchCommand(SocketClient *cli, char *cmd) {
|
||||
|
||||
char *cm, *last;
|
||||
|
||||
if (!(cm = strtok_r(cmd, ":", &last))) {
|
||||
cli->sendMsg("BAD_MSG");
|
||||
return;
|
||||
}
|
||||
|
||||
FrameworkCommandCollection::iterator i;
|
||||
|
||||
for (i = mCommands->begin(); i != mCommands->end(); ++i) {
|
||||
FrameworkCommand *c = *i;
|
||||
|
||||
if (!strncmp(cmd, c->getCommand(), strlen(c->getCommand()))) {
|
||||
if (c->runCommand(cmd)) {
|
||||
if (!strcmp(cm, c->getCommand())) {
|
||||
if (c->runCommand(cli, cmd)) {
|
||||
LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno));
|
||||
}
|
||||
return;
|
||||
|
|
@ -73,5 +82,6 @@ void FrameworkListener::dispatchCommand(char *cmd) {
|
|||
}
|
||||
|
||||
LOGE("No cmd handlers defined for '%s'", cmd);
|
||||
cli->sendMsg("UNKNOWN_CMD");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <cutils/config_utils.h>
|
||||
#include <cutils/cpu_info.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <cutils/sockets.h>
|
||||
|
||||
#define LOG_TAG "FrameworkManager"
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <sysutils/FrameworkManager.h>
|
||||
#include <sysutils/FrameworkListener.h>
|
||||
|
||||
FrameworkManager::FrameworkManager(FrameworkListener *Listener) {
|
||||
mDoorbell = -1;
|
||||
mFwSock = -1;
|
||||
mListener = Listener;
|
||||
|
||||
pthread_mutex_init(&mWriteMutex, NULL);
|
||||
}
|
||||
|
||||
int FrameworkManager::run() {
|
||||
|
||||
if (mListener->run()) {
|
||||
LOGE("Error running listener (%s)", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ========
|
||||
* Privates
|
||||
* ========
|
||||
*/
|
||||
|
||||
int FrameworkManager::sendMsg(char *msg) {
|
||||
LOGD("FrameworkManager::sendMsg(%s)", msg);
|
||||
if (mFwSock < 0) {
|
||||
errno = EHOSTUNREACH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mWriteMutex);
|
||||
if (write(mFwSock, msg, strlen(msg) +1) < 0) {
|
||||
LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno));
|
||||
}
|
||||
pthread_mutex_unlock(&mWriteMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FrameworkManager::sendMsg(char *msg, char *data) {
|
||||
char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1);
|
||||
if (!buffer) {
|
||||
errno = -ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
strcpy(buffer, msg);
|
||||
strcat(buffer, data);
|
||||
return sendMsg(buffer);
|
||||
}
|
||||
|
|
@ -29,8 +29,9 @@ NetlinkListener::NetlinkListener(int socket) :
|
|||
SocketListener(socket, false) {
|
||||
}
|
||||
|
||||
bool NetlinkListener::onDataAvailable(int socket)
|
||||
bool NetlinkListener::onDataAvailable(SocketClient *cli)
|
||||
{
|
||||
int socket = cli->getSocket();
|
||||
LOGD("NetlinkListener::onDataAvailable()");
|
||||
|
||||
int count;
|
||||
|
|
|
|||
41
libsysutils/src/SocketClient.cpp
Normal file
41
libsysutils/src/SocketClient.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include <alloca.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define LOG_TAG "SocketClient"
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <sysutils/SocketClient.h>
|
||||
|
||||
SocketClient::SocketClient(int socket) {
|
||||
mSocket = socket;
|
||||
pthread_mutex_init(&mWriteMutex, NULL);
|
||||
}
|
||||
|
||||
int SocketClient::sendMsg(char *msg) {
|
||||
LOGD("SocketClient::sendMsg(%s)", msg);
|
||||
if (mSocket < 0) {
|
||||
errno = EHOSTUNREACH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&mWriteMutex);
|
||||
if (write(mSocket, msg, strlen(msg) +1) < 0) {
|
||||
LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno));
|
||||
}
|
||||
pthread_mutex_unlock(&mWriteMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SocketClient::sendMsg(char *msg, char *data) {
|
||||
char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1);
|
||||
if (!buffer) {
|
||||
errno = -ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
strcpy(buffer, msg);
|
||||
strcat(buffer, data);
|
||||
return sendMsg(buffer);
|
||||
}
|
||||
|
||||
|
|
@ -24,26 +24,28 @@
|
|||
|
||||
#define LOG_TAG "SocketListener"
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <cutils/sockets.h>
|
||||
|
||||
#include <sysutils/SocketListener.h>
|
||||
#include <sysutils/SocketClient.h>
|
||||
|
||||
SocketListener::SocketListener(const char *socketName, bool acceptClients) {
|
||||
mAcceptClients = acceptClients;
|
||||
mCsock = -1;
|
||||
SocketListener::SocketListener(const char *socketName, bool listen) {
|
||||
mListen = listen;
|
||||
mSocketName = socketName;
|
||||
mSock = -1;
|
||||
pthread_mutex_init(&mClientsLock, NULL);
|
||||
mClients = new SocketClientCollection();
|
||||
}
|
||||
|
||||
SocketListener::SocketListener(int socketFd, bool acceptClients) {
|
||||
mAcceptClients = acceptClients;
|
||||
mCsock = -1;
|
||||
SocketListener::SocketListener(int socketFd, bool listen) {
|
||||
mListen = listen;
|
||||
mSocketName = NULL;
|
||||
mSock = socketFd;
|
||||
pthread_mutex_init(&mClientsLock, NULL);
|
||||
mClients = new SocketClientCollection();
|
||||
}
|
||||
|
||||
int SocketListener::run() {
|
||||
int SocketListener::startListener() {
|
||||
|
||||
if (!mSocketName && mSock == -1) {
|
||||
errno = EINVAL;
|
||||
|
|
@ -56,72 +58,155 @@ int SocketListener::run() {
|
|||
}
|
||||
}
|
||||
|
||||
if (mAcceptClients) {
|
||||
if (listen(mSock, 4) < 0) {
|
||||
LOGE("Unable to listen on socket (%s)", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (mListen && listen(mSock, 4) < 0) {
|
||||
LOGE("Unable to listen on socket (%s)", strerror(errno));
|
||||
return -1;
|
||||
} else if (!mListen) {
|
||||
mClients->push_back(new SocketClient(mSock));
|
||||
LOGD("Created phantom client");
|
||||
}
|
||||
|
||||
if (pipe(mCtrlPipe))
|
||||
return -1;
|
||||
|
||||
if (pthread_create(&mThread, NULL, SocketListener::threadStart, this))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SocketListener::stopListener() {
|
||||
char c = 0;
|
||||
|
||||
if (write(mCtrlPipe[1], &c, 1) != 1) {
|
||||
LOGE("Error writing to control pipe (%s)", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOGD("Signaled listener thread - waiting for it to die");
|
||||
void *ret;
|
||||
if (pthread_join(mThread, &ret)) {
|
||||
LOGE("Error joining to listener thread (%s)", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
LOGD("Listener stopped");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *SocketListener::threadStart(void *obj) {
|
||||
SocketListener *me = reinterpret_cast<SocketListener *>(obj);
|
||||
|
||||
me->runListener();
|
||||
LOGD("Listener thread shutting down");
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SocketListener::runListener() {
|
||||
|
||||
while(1) {
|
||||
SocketClientCollection::iterator it;
|
||||
fd_set read_fds;
|
||||
struct timeval to;
|
||||
int max = 0;
|
||||
int rc = 0;
|
||||
|
||||
to.tv_sec = 60 * 60;
|
||||
to.tv_usec = 0;
|
||||
|
||||
int max = 0;
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
|
||||
if ((mAcceptClients == false) ||
|
||||
(mAcceptClients == true && mCsock == -1)) {
|
||||
FD_SET(mSock, &read_fds);
|
||||
if (mListen) {
|
||||
max = mSock;
|
||||
} else if (mCsock != -1) {
|
||||
FD_SET(mCsock, &read_fds);
|
||||
max = mCsock;
|
||||
FD_SET(mSock, &read_fds);
|
||||
}
|
||||
|
||||
FD_SET(mCtrlPipe[0], &read_fds);
|
||||
if (mCtrlPipe[0] > max)
|
||||
max = mCtrlPipe[0];
|
||||
|
||||
pthread_mutex_lock(&mClientsLock);
|
||||
for (it = mClients->begin(); it != mClients->end(); ++it) {
|
||||
FD_SET((*it)->getSocket(), &read_fds);
|
||||
if ((*it)->getSocket() > max)
|
||||
max = (*it)->getSocket();
|
||||
}
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
|
||||
if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) {
|
||||
LOGE("select failed (%s)", strerror(errno));
|
||||
return -errno;
|
||||
} else if (!rc)
|
||||
sleep(1);
|
||||
continue;
|
||||
else if (FD_ISSET(mSock, &read_fds)) {
|
||||
/*
|
||||
* If we're accepting client connections then
|
||||
* accept and gobble the event. Otherwise
|
||||
* pass it on to the handlers.
|
||||
*/
|
||||
if (mAcceptClients) {
|
||||
struct sockaddr addr;
|
||||
socklen_t alen = sizeof(addr);
|
||||
} else if (!rc) {
|
||||
LOGD("select timeout");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mCsock = accept(mSock, &addr, &alen)) < 0) {
|
||||
LOGE("accept failed (%s)", strerror(errno));
|
||||
return -errno;
|
||||
if (FD_ISSET(mCtrlPipe[0], &read_fds)) {
|
||||
LOGD("Control message received");
|
||||
break;
|
||||
}
|
||||
if (mListen && FD_ISSET(mSock, &read_fds)) {
|
||||
struct sockaddr addr;
|
||||
socklen_t alen = sizeof(addr);
|
||||
int c;
|
||||
|
||||
if ((c = accept(mSock, &addr, &alen)) < 0) {
|
||||
LOGE("accept failed (%s)", strerror(errno));
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
LOGD("SocketListener client connection accepted");
|
||||
pthread_mutex_lock(&mClientsLock);
|
||||
mClients->push_back(new SocketClient(c));
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
}
|
||||
|
||||
do {
|
||||
pthread_mutex_lock(&mClientsLock);
|
||||
for (it = mClients->begin(); it != mClients->end(); ++it) {
|
||||
int fd = (*it)->getSocket();
|
||||
if (FD_ISSET(fd, &read_fds)) {
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
if (!onDataAvailable(*it)) {
|
||||
LOGD("SocketListener closing client socket");
|
||||
close(fd);
|
||||
pthread_mutex_lock(&mClientsLock);
|
||||
delete *it;
|
||||
it = mClients->erase(it);
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
}
|
||||
FD_CLR(fd, &read_fds);
|
||||
continue;
|
||||
}
|
||||
LOGD("SocketListener client connection accepted");
|
||||
} else if (!onDataAvailable(mSock)) {
|
||||
LOGW("SocketListener closing listening socket (Will shut down)");
|
||||
close(mSock);
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
} else if ((FD_ISSET(mCsock, &read_fds)) &&
|
||||
!onDataAvailable(mCsock)) {
|
||||
/*
|
||||
* Once mCsock == -1, we'll start
|
||||
* accepting connections on mSock again.
|
||||
*/
|
||||
LOGD("SocketListener closing client socket");
|
||||
close(mCsock);
|
||||
mCsock = -1;
|
||||
}
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
} while (0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SocketListener::onDataAvailable(int socket) {
|
||||
return false;
|
||||
void SocketListener::sendBroadcast(char *msg) {
|
||||
pthread_mutex_lock(&mClientsLock);
|
||||
SocketClientCollection::iterator i;
|
||||
|
||||
for (i = mClients->begin(); i != mClients->end(); ++i) {
|
||||
if ((*i)->sendMsg(msg)) {
|
||||
LOGW("Error sending broadcast (%s)", strerror(errno));
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
}
|
||||
|
||||
void SocketListener::sendBroadcast(char *msg, char *data) {
|
||||
pthread_mutex_lock(&mClientsLock);
|
||||
SocketClientCollection::iterator i;
|
||||
|
||||
for (i = mClients->begin(); i != mClients->end(); ++i) {
|
||||
if ((*i)->sendMsg(msg, data)) {
|
||||
LOGW("Error sending broadcast (%s)", strerror(errno));
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue