system/corennnnn
修订版 | fa644ffe944c01a9b00f8d7676d58394fabee285 (tree) |
---|---|
时间 | 2009-05-11 01:26:42 |
作者 | San Mehat <san@goog...> |
Commiter | San Mehat |
libsysutils: Add multiple client support and fix some bugs
@@ -0,0 +1,21 @@ | ||
1 | +#ifndef _FRAMEWORK_CLIENT_H | |
2 | +#define _FRAMEWORK_CLIENT_H | |
3 | + | |
4 | +#include "../../../frameworks/base/include/utils/List.h" | |
5 | + | |
6 | +#include <pthread.h> | |
7 | + | |
8 | +class FrameworkClient { | |
9 | + int mSocket; | |
10 | + pthread_mutex_t mWriteMutex; | |
11 | + | |
12 | +public: | |
13 | + FrameworkClient(int sock); | |
14 | + virtual ~FrameworkClient() {} | |
15 | + | |
16 | + int sendMsg(char *msg); | |
17 | + int sendMsg(char *msg, char *data); | |
18 | +}; | |
19 | + | |
20 | +typedef android::List<FrameworkClient *> FrameworkClientCollection; | |
21 | +#endif |
@@ -18,6 +18,7 @@ | ||
18 | 18 | |
19 | 19 | #include "../../../frameworks/base/include/utils/List.h" |
20 | 20 | |
21 | +class SocketClient; | |
21 | 22 | |
22 | 23 | class FrameworkCommand { |
23 | 24 | private: |
@@ -28,7 +29,7 @@ public: | ||
28 | 29 | FrameworkCommand(const char *cmd); |
29 | 30 | virtual ~FrameworkCommand() { } |
30 | 31 | |
31 | - virtual int runCommand(char *data); | |
32 | + virtual int runCommand(SocketClient *c, char *data) = 0; | |
32 | 33 | |
33 | 34 | const char *getCommand() { return mCommand; } |
34 | 35 | }; |
@@ -19,6 +19,8 @@ | ||
19 | 19 | #include "SocketListener.h" |
20 | 20 | #include "FrameworkCommand.h" |
21 | 21 | |
22 | +class SocketClient; | |
23 | + | |
22 | 24 | class FrameworkListener : public SocketListener { |
23 | 25 | private: |
24 | 26 | FrameworkCommandCollection *mCommands; |
@@ -29,9 +31,9 @@ public: | ||
29 | 31 | |
30 | 32 | protected: |
31 | 33 | void registerCmd(FrameworkCommand *cmd); |
32 | - virtual bool onDataAvailable(int socket); | |
34 | + virtual bool onDataAvailable(SocketClient *c); | |
33 | 35 | |
34 | 36 | private: |
35 | - void dispatchCommand(char *cmd); | |
37 | + void dispatchCommand(SocketClient *c, char *cmd); | |
36 | 38 | }; |
37 | 39 | #endif |
@@ -1,40 +0,0 @@ | ||
1 | -/* | |
2 | - * Copyright (C) 2008 The Android Open Source Project | |
3 | - * | |
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | - * you may not use this file except in compliance with the License. | |
6 | - * You may obtain a copy of the License at | |
7 | - * | |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | - * | |
10 | - * Unless required by applicable law or agreed to in writing, software | |
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | - * See the License for the specific language governing permissions and | |
14 | - * limitations under the License. | |
15 | - */ | |
16 | -#ifndef _FRAMEWORKMANAGER_H | |
17 | -#define _FRAMEWORKMANAGER_H | |
18 | - | |
19 | -#include <pthread.h> | |
20 | - | |
21 | -class FrameworkListener; | |
22 | - | |
23 | -class FrameworkManager { | |
24 | - int mDoorbell; // Socket used to accept connections from framework | |
25 | - int mFwSock; // Socket used to communicate with framework | |
26 | - const char *mSocketName; | |
27 | - | |
28 | - FrameworkListener *mListener; | |
29 | - | |
30 | - pthread_mutex_t mWriteMutex; | |
31 | - | |
32 | -public: | |
33 | - FrameworkManager(FrameworkListener *Listener); | |
34 | - virtual ~FrameworkManager() {} | |
35 | - | |
36 | - int run(); | |
37 | - int sendMsg(char *msg); | |
38 | - int sendMsg(char *msg, char *data); | |
39 | -}; | |
40 | -#endif |
@@ -27,6 +27,6 @@ public: | ||
27 | 27 | NetlinkListener(int socket); |
28 | 28 | virtual ~NetlinkListener() {} |
29 | 29 | protected: |
30 | - virtual bool onDataAvailable(int socket); | |
30 | + virtual bool onDataAvailable(SocketClient *cli); | |
31 | 31 | }; |
32 | 32 | #endif |
@@ -0,0 +1,23 @@ | ||
1 | +#ifndef _SOCKET_CLIENT_H | |
2 | +#define _SOCKET_CLIENT_H | |
3 | + | |
4 | +#include "../../../frameworks/base/include/utils/List.h" | |
5 | + | |
6 | +#include <pthread.h> | |
7 | + | |
8 | +class SocketClient { | |
9 | + int mSocket; | |
10 | + pthread_mutex_t mWriteMutex; | |
11 | + | |
12 | +public: | |
13 | + SocketClient(int sock); | |
14 | + virtual ~SocketClient() {} | |
15 | + | |
16 | + int getSocket() { return mSocket; } | |
17 | + | |
18 | + int sendMsg(char *msg); | |
19 | + int sendMsg(char *msg, char *data); | |
20 | +}; | |
21 | + | |
22 | +typedef android::List<SocketClient *> SocketClientCollection; | |
23 | +#endif |
@@ -16,20 +16,35 @@ | ||
16 | 16 | #ifndef _SOCKETLISTENER_H |
17 | 17 | #define _SOCKETLISTENER_H |
18 | 18 | |
19 | +#include <pthread.h> | |
20 | + | |
21 | +#include <sysutils/SocketClient.h> | |
22 | + | |
19 | 23 | class SocketListener { |
20 | - int mSock; | |
21 | - int mCsock; | |
22 | - int mAcceptClients; | |
23 | - const char *mSocketName; | |
24 | + int mSock; | |
25 | + const char *mSocketName; | |
26 | + SocketClientCollection *mClients; | |
27 | + pthread_mutex_t mClientsLock; | |
28 | + bool mListen; | |
29 | + int mCtrlPipe[2]; | |
30 | + pthread_t mThread; | |
24 | 31 | |
25 | 32 | public: |
26 | - SocketListener(const char *socketName, bool acceptClients); | |
27 | - SocketListener(int socketFd, bool acceptClients); | |
33 | + SocketListener(const char *socketNames, bool listen); | |
34 | + SocketListener(int socketFd, bool listen); | |
28 | 35 | |
29 | 36 | virtual ~SocketListener() {} |
30 | - virtual int run(); | |
37 | + int startListener(); | |
38 | + int stopListener(); | |
39 | + | |
40 | + void sendBroadcast(char *msg); | |
41 | + void sendBroadcast(char *msg, char *data); | |
31 | 42 | |
32 | 43 | protected: |
33 | - virtual bool onDataAvailable(int socket); | |
44 | + virtual bool onDataAvailable(SocketClient *c) = 0; | |
45 | + | |
46 | +private: | |
47 | + static void *threadStart(void *obj); | |
48 | + void runListener(); | |
34 | 49 | }; |
35 | 50 | #endif |
@@ -3,12 +3,12 @@ LOCAL_PATH:= $(call my-dir) | ||
3 | 3 | include $(CLEAR_VARS) |
4 | 4 | |
5 | 5 | LOCAL_SRC_FILES:= \ |
6 | - src/FrameworkManager.cpp \ | |
7 | 6 | src/SocketListener.cpp \ |
8 | 7 | src/FrameworkListener.cpp \ |
9 | 8 | src/NetlinkListener.cpp \ |
10 | 9 | src/NetlinkEvent.cpp \ |
11 | 10 | src/FrameworkCommand.cpp \ |
11 | + src/SocketClient.cpp \ | |
12 | 12 | |
13 | 13 | LOCAL_MODULE:= libsysutils |
14 | 14 |
@@ -0,0 +1,41 @@ | ||
1 | +#include <alloca.h> | |
2 | +#include <errno.h> | |
3 | +#include <sys/types.h> | |
4 | +#include <pthread.h> | |
5 | + | |
6 | +#define LOG_TAG "FrameworkClient" | |
7 | +#include <cutils/log.h> | |
8 | + | |
9 | +#include <sysutils/FrameworkClient.h> | |
10 | + | |
11 | +FrameworkClient::FrameworkClient(int socket) { | |
12 | + mSocket = socket; | |
13 | + pthread_mutex_init(&mWriteMutex, NULL); | |
14 | +} | |
15 | + | |
16 | +int FrameworkClient::sendMsg(char *msg) { | |
17 | + LOGD("FrameworkClient::sendMsg(%s)", msg); | |
18 | + if (mSocket < 0) { | |
19 | + errno = EHOSTUNREACH; | |
20 | + return -1; | |
21 | + } | |
22 | + | |
23 | + pthread_mutex_lock(&mWriteMutex); | |
24 | + if (write(mSocket, msg, strlen(msg) +1) < 0) { | |
25 | + LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno)); | |
26 | + } | |
27 | + pthread_mutex_unlock(&mWriteMutex); | |
28 | + return 0; | |
29 | +} | |
30 | + | |
31 | +int FrameworkClient::sendMsg(char *msg, char *data) { | |
32 | + char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1); | |
33 | + if (!buffer) { | |
34 | + errno = -ENOMEM; | |
35 | + return -1; | |
36 | + } | |
37 | + strcpy(buffer, msg); | |
38 | + strcat(buffer, data); | |
39 | + return sendMsg(buffer); | |
40 | +} | |
41 | + |
@@ -25,7 +25,7 @@ FrameworkCommand::FrameworkCommand(const char *cmd) { | ||
25 | 25 | mCommand = cmd; |
26 | 26 | } |
27 | 27 | |
28 | -int FrameworkCommand::runCommand(char *data) { | |
28 | +int FrameworkCommand::runCommand(SocketClient *c, char *data) { | |
29 | 29 | LOGW("Command %s has no run handler!", getCommand()); |
30 | 30 | errno = ENOSYS; |
31 | 31 | return -1; |
@@ -22,17 +22,18 @@ | ||
22 | 22 | |
23 | 23 | #include <sysutils/FrameworkListener.h> |
24 | 24 | #include <sysutils/FrameworkCommand.h> |
25 | +#include <sysutils/SocketClient.h> | |
25 | 26 | |
26 | 27 | FrameworkListener::FrameworkListener(const char *socketName) : |
27 | 28 | SocketListener(socketName, true) { |
28 | 29 | mCommands = new FrameworkCommandCollection(); |
29 | 30 | } |
30 | 31 | |
31 | -bool FrameworkListener::onDataAvailable(int socket) { | |
32 | +bool FrameworkListener::onDataAvailable(SocketClient *c) { | |
32 | 33 | char buffer[101]; |
33 | 34 | int len; |
34 | 35 | |
35 | - if ((len = read(socket, buffer, sizeof(buffer) -1)) < 0) { | |
36 | + if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) { | |
36 | 37 | LOGE("read() failed (%s)", strerror(errno)); |
37 | 38 | return errno; |
38 | 39 | } else if (!len) { |
@@ -47,7 +48,7 @@ bool FrameworkListener::onDataAvailable(int socket) { | ||
47 | 48 | |
48 | 49 | for (i = 0; i < len; i++) { |
49 | 50 | if (buffer[i] == '\0') { |
50 | - dispatchCommand(buffer + start); | |
51 | + dispatchCommand(c, buffer + start); | |
51 | 52 | start = i + 1; |
52 | 53 | } |
53 | 54 | } |
@@ -58,14 +59,22 @@ void FrameworkListener::registerCmd(FrameworkCommand *cmd) { | ||
58 | 59 | mCommands->push_back(cmd); |
59 | 60 | } |
60 | 61 | |
61 | -void FrameworkListener::dispatchCommand(char *cmd) { | |
62 | +void FrameworkListener::dispatchCommand(SocketClient *cli, char *cmd) { | |
63 | + | |
64 | + char *cm, *last; | |
65 | + | |
66 | + if (!(cm = strtok_r(cmd, ":", &last))) { | |
67 | + cli->sendMsg("BAD_MSG"); | |
68 | + return; | |
69 | + } | |
70 | + | |
62 | 71 | FrameworkCommandCollection::iterator i; |
63 | 72 | |
64 | 73 | for (i = mCommands->begin(); i != mCommands->end(); ++i) { |
65 | 74 | FrameworkCommand *c = *i; |
66 | 75 | |
67 | - if (!strncmp(cmd, c->getCommand(), strlen(c->getCommand()))) { | |
68 | - if (c->runCommand(cmd)) { | |
76 | + if (!strcmp(cm, c->getCommand())) { | |
77 | + if (c->runCommand(cli, cmd)) { | |
69 | 78 | LOGW("Handler '%s' error (%s)", c->getCommand(), strerror(errno)); |
70 | 79 | } |
71 | 80 | return; |
@@ -73,5 +82,6 @@ void FrameworkListener::dispatchCommand(char *cmd) { | ||
73 | 82 | } |
74 | 83 | |
75 | 84 | LOGE("No cmd handlers defined for '%s'", cmd); |
85 | + cli->sendMsg("UNKNOWN_CMD"); | |
86 | + return; | |
76 | 87 | } |
77 | - |
@@ -1,83 +0,0 @@ | ||
1 | -/* | |
2 | - * Copyright (C) 2008 The Android Open Source Project | |
3 | - * | |
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | - * you may not use this file except in compliance with the License. | |
6 | - * You may obtain a copy of the License at | |
7 | - * | |
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | - * | |
10 | - * Unless required by applicable law or agreed to in writing, software | |
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | - * See the License for the specific language governing permissions and | |
14 | - * limitations under the License. | |
15 | - */ | |
16 | -#include <stdio.h> | |
17 | -#include <errno.h> | |
18 | -#include <stdlib.h> | |
19 | -#include <sys/socket.h> | |
20 | -#include <sys/select.h> | |
21 | -#include <sys/time.h> | |
22 | -#include <sys/types.h> | |
23 | -#include <sys/un.h> | |
24 | - | |
25 | -#include <cutils/config_utils.h> | |
26 | -#include <cutils/cpu_info.h> | |
27 | -#include <cutils/properties.h> | |
28 | -#include <cutils/sockets.h> | |
29 | - | |
30 | -#define LOG_TAG "FrameworkManager" | |
31 | -#include <cutils/log.h> | |
32 | - | |
33 | -#include <sysutils/FrameworkManager.h> | |
34 | -#include <sysutils/FrameworkListener.h> | |
35 | - | |
36 | -FrameworkManager::FrameworkManager(FrameworkListener *Listener) { | |
37 | - mDoorbell = -1; | |
38 | - mFwSock = -1; | |
39 | - mListener = Listener; | |
40 | - | |
41 | - pthread_mutex_init(&mWriteMutex, NULL); | |
42 | -} | |
43 | - | |
44 | -int FrameworkManager::run() { | |
45 | - | |
46 | - if (mListener->run()) { | |
47 | - LOGE("Error running listener (%s)", strerror(errno)); | |
48 | - return -1; | |
49 | - } | |
50 | - | |
51 | - return 0; | |
52 | -} | |
53 | - | |
54 | -/* ======== | |
55 | - * Privates | |
56 | - * ======== | |
57 | - */ | |
58 | - | |
59 | -int FrameworkManager::sendMsg(char *msg) { | |
60 | - LOGD("FrameworkManager::sendMsg(%s)", msg); | |
61 | - if (mFwSock < 0) { | |
62 | - errno = EHOSTUNREACH; | |
63 | - return -1; | |
64 | - } | |
65 | - | |
66 | - pthread_mutex_lock(&mWriteMutex); | |
67 | - if (write(mFwSock, msg, strlen(msg) +1) < 0) { | |
68 | - LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno)); | |
69 | - } | |
70 | - pthread_mutex_unlock(&mWriteMutex); | |
71 | - return 0; | |
72 | -} | |
73 | - | |
74 | -int FrameworkManager::sendMsg(char *msg, char *data) { | |
75 | - char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1); | |
76 | - if (!buffer) { | |
77 | - errno = -ENOMEM; | |
78 | - return -1; | |
79 | - } | |
80 | - strcpy(buffer, msg); | |
81 | - strcat(buffer, data); | |
82 | - return sendMsg(buffer); | |
83 | -} |
@@ -29,8 +29,9 @@ NetlinkListener::NetlinkListener(int socket) : | ||
29 | 29 | SocketListener(socket, false) { |
30 | 30 | } |
31 | 31 | |
32 | -bool NetlinkListener::onDataAvailable(int socket) | |
32 | +bool NetlinkListener::onDataAvailable(SocketClient *cli) | |
33 | 33 | { |
34 | + int socket = cli->getSocket(); | |
34 | 35 | LOGD("NetlinkListener::onDataAvailable()"); |
35 | 36 | |
36 | 37 | int count; |
@@ -0,0 +1,41 @@ | ||
1 | +#include <alloca.h> | |
2 | +#include <errno.h> | |
3 | +#include <sys/types.h> | |
4 | +#include <pthread.h> | |
5 | + | |
6 | +#define LOG_TAG "SocketClient" | |
7 | +#include <cutils/log.h> | |
8 | + | |
9 | +#include <sysutils/SocketClient.h> | |
10 | + | |
11 | +SocketClient::SocketClient(int socket) { | |
12 | + mSocket = socket; | |
13 | + pthread_mutex_init(&mWriteMutex, NULL); | |
14 | +} | |
15 | + | |
16 | +int SocketClient::sendMsg(char *msg) { | |
17 | + LOGD("SocketClient::sendMsg(%s)", msg); | |
18 | + if (mSocket < 0) { | |
19 | + errno = EHOSTUNREACH; | |
20 | + return -1; | |
21 | + } | |
22 | + | |
23 | + pthread_mutex_lock(&mWriteMutex); | |
24 | + if (write(mSocket, msg, strlen(msg) +1) < 0) { | |
25 | + LOGW("Unable to send msg '%s' (%s)", msg, strerror(errno)); | |
26 | + } | |
27 | + pthread_mutex_unlock(&mWriteMutex); | |
28 | + return 0; | |
29 | +} | |
30 | + | |
31 | +int SocketClient::sendMsg(char *msg, char *data) { | |
32 | + char *buffer = (char *) alloca(strlen(msg) + strlen(data) + 1); | |
33 | + if (!buffer) { | |
34 | + errno = -ENOMEM; | |
35 | + return -1; | |
36 | + } | |
37 | + strcpy(buffer, msg); | |
38 | + strcat(buffer, data); | |
39 | + return sendMsg(buffer); | |
40 | +} | |
41 | + |
@@ -24,26 +24,28 @@ | ||
24 | 24 | |
25 | 25 | #define LOG_TAG "SocketListener" |
26 | 26 | #include <cutils/log.h> |
27 | - | |
28 | 27 | #include <cutils/sockets.h> |
29 | 28 | |
30 | 29 | #include <sysutils/SocketListener.h> |
30 | +#include <sysutils/SocketClient.h> | |
31 | 31 | |
32 | -SocketListener::SocketListener(const char *socketName, bool acceptClients) { | |
33 | - mAcceptClients = acceptClients; | |
34 | - mCsock = -1; | |
32 | +SocketListener::SocketListener(const char *socketName, bool listen) { | |
33 | + mListen = listen; | |
35 | 34 | mSocketName = socketName; |
36 | 35 | mSock = -1; |
36 | + pthread_mutex_init(&mClientsLock, NULL); | |
37 | + mClients = new SocketClientCollection(); | |
37 | 38 | } |
38 | 39 | |
39 | -SocketListener::SocketListener(int socketFd, bool acceptClients) { | |
40 | - mAcceptClients = acceptClients; | |
41 | - mCsock = -1; | |
40 | +SocketListener::SocketListener(int socketFd, bool listen) { | |
41 | + mListen = listen; | |
42 | 42 | mSocketName = NULL; |
43 | 43 | mSock = socketFd; |
44 | + pthread_mutex_init(&mClientsLock, NULL); | |
45 | + mClients = new SocketClientCollection(); | |
44 | 46 | } |
45 | 47 | |
46 | -int SocketListener::run() { | |
48 | +int SocketListener::startListener() { | |
47 | 49 | |
48 | 50 | if (!mSocketName && mSock == -1) { |
49 | 51 | errno = EINVAL; |
@@ -56,72 +58,155 @@ int SocketListener::run() { | ||
56 | 58 | } |
57 | 59 | } |
58 | 60 | |
59 | - if (mAcceptClients) { | |
60 | - if (listen(mSock, 4) < 0) { | |
61 | - LOGE("Unable to listen on socket (%s)", strerror(errno)); | |
62 | - return -1; | |
63 | - } | |
61 | + if (mListen && listen(mSock, 4) < 0) { | |
62 | + LOGE("Unable to listen on socket (%s)", strerror(errno)); | |
63 | + return -1; | |
64 | + } else if (!mListen) { | |
65 | + mClients->push_back(new SocketClient(mSock)); | |
66 | + LOGD("Created phantom client"); | |
64 | 67 | } |
65 | 68 | |
69 | + if (pipe(mCtrlPipe)) | |
70 | + return -1; | |
71 | + | |
72 | + if (pthread_create(&mThread, NULL, SocketListener::threadStart, this)) | |
73 | + return -1; | |
74 | + | |
75 | + return 0; | |
76 | +} | |
77 | + | |
78 | +int SocketListener::stopListener() { | |
79 | + char c = 0; | |
80 | + | |
81 | + if (write(mCtrlPipe[1], &c, 1) != 1) { | |
82 | + LOGE("Error writing to control pipe (%s)", strerror(errno)); | |
83 | + return -1; | |
84 | + } | |
85 | + | |
86 | + LOGD("Signaled listener thread - waiting for it to die"); | |
87 | + void *ret; | |
88 | + if (pthread_join(mThread, &ret)) { | |
89 | + LOGE("Error joining to listener thread (%s)", strerror(errno)); | |
90 | + return -1; | |
91 | + } | |
92 | + LOGD("Listener stopped"); | |
93 | + return 0; | |
94 | +} | |
95 | + | |
96 | +void *SocketListener::threadStart(void *obj) { | |
97 | + SocketListener *me = reinterpret_cast<SocketListener *>(obj); | |
98 | + | |
99 | + me->runListener(); | |
100 | + LOGD("Listener thread shutting down"); | |
101 | + pthread_exit(NULL); | |
102 | + return NULL; | |
103 | +} | |
104 | + | |
105 | +void SocketListener::runListener() { | |
106 | + | |
66 | 107 | while(1) { |
108 | + SocketClientCollection::iterator it; | |
67 | 109 | fd_set read_fds; |
68 | 110 | struct timeval to; |
69 | - int max = 0; | |
70 | 111 | int rc = 0; |
71 | 112 | |
72 | 113 | to.tv_sec = 60 * 60; |
73 | 114 | to.tv_usec = 0; |
74 | 115 | |
116 | + int max = 0; | |
117 | + | |
75 | 118 | FD_ZERO(&read_fds); |
76 | 119 | |
77 | - if ((mAcceptClients == false) || | |
78 | - (mAcceptClients == true && mCsock == -1)) { | |
79 | - FD_SET(mSock, &read_fds); | |
120 | + if (mListen) { | |
80 | 121 | max = mSock; |
81 | - } else if (mCsock != -1) { | |
82 | - FD_SET(mCsock, &read_fds); | |
83 | - max = mCsock; | |
122 | + FD_SET(mSock, &read_fds); | |
84 | 123 | } |
85 | 124 | |
125 | + FD_SET(mCtrlPipe[0], &read_fds); | |
126 | + if (mCtrlPipe[0] > max) | |
127 | + max = mCtrlPipe[0]; | |
128 | + | |
129 | + pthread_mutex_lock(&mClientsLock); | |
130 | + for (it = mClients->begin(); it != mClients->end(); ++it) { | |
131 | + FD_SET((*it)->getSocket(), &read_fds); | |
132 | + if ((*it)->getSocket() > max) | |
133 | + max = (*it)->getSocket(); | |
134 | + } | |
135 | + pthread_mutex_unlock(&mClientsLock); | |
136 | + | |
86 | 137 | if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) { |
87 | 138 | LOGE("select failed (%s)", strerror(errno)); |
88 | - return -errno; | |
89 | - } else if (!rc) | |
139 | + sleep(1); | |
90 | 140 | continue; |
91 | - else if (FD_ISSET(mSock, &read_fds)) { | |
92 | - /* | |
93 | - * If we're accepting client connections then | |
94 | - * accept and gobble the event. Otherwise | |
95 | - * pass it on to the handlers. | |
96 | - */ | |
97 | - if (mAcceptClients) { | |
98 | - struct sockaddr addr; | |
99 | - socklen_t alen = sizeof(addr); | |
100 | - | |
101 | - if ((mCsock = accept(mSock, &addr, &alen)) < 0) { | |
102 | - LOGE("accept failed (%s)", strerror(errno)); | |
103 | - return -errno; | |
104 | - } | |
105 | - LOGD("SocketListener client connection accepted"); | |
106 | - } else if (!onDataAvailable(mSock)) { | |
107 | - LOGW("SocketListener closing listening socket (Will shut down)"); | |
108 | - close(mSock); | |
109 | - return -ESHUTDOWN; | |
141 | + } else if (!rc) { | |
142 | + LOGD("select timeout"); | |
143 | + continue; | |
144 | + } | |
145 | + | |
146 | + if (FD_ISSET(mCtrlPipe[0], &read_fds)) { | |
147 | + LOGD("Control message received"); | |
148 | + break; | |
149 | + } | |
150 | + if (mListen && FD_ISSET(mSock, &read_fds)) { | |
151 | + struct sockaddr addr; | |
152 | + socklen_t alen = sizeof(addr); | |
153 | + int c; | |
154 | + | |
155 | + if ((c = accept(mSock, &addr, &alen)) < 0) { | |
156 | + LOGE("accept failed (%s)", strerror(errno)); | |
157 | + sleep(1); | |
158 | + continue; | |
110 | 159 | } |
111 | - } else if ((FD_ISSET(mCsock, &read_fds)) && | |
112 | - !onDataAvailable(mCsock)) { | |
113 | - /* | |
114 | - * Once mCsock == -1, we'll start | |
115 | - * accepting connections on mSock again. | |
116 | - */ | |
117 | - LOGD("SocketListener closing client socket"); | |
118 | - close(mCsock); | |
119 | - mCsock = -1; | |
160 | + LOGD("SocketListener client connection accepted"); | |
161 | + pthread_mutex_lock(&mClientsLock); | |
162 | + mClients->push_back(new SocketClient(c)); | |
163 | + pthread_mutex_unlock(&mClientsLock); | |
164 | + } | |
165 | + | |
166 | + do { | |
167 | + pthread_mutex_lock(&mClientsLock); | |
168 | + for (it = mClients->begin(); it != mClients->end(); ++it) { | |
169 | + int fd = (*it)->getSocket(); | |
170 | + if (FD_ISSET(fd, &read_fds)) { | |
171 | + pthread_mutex_unlock(&mClientsLock); | |
172 | + if (!onDataAvailable(*it)) { | |
173 | + LOGD("SocketListener closing client socket"); | |
174 | + close(fd); | |
175 | + pthread_mutex_lock(&mClientsLock); | |
176 | + delete *it; | |
177 | + it = mClients->erase(it); | |
178 | + pthread_mutex_unlock(&mClientsLock); | |
179 | + } | |
180 | + FD_CLR(fd, &read_fds); | |
181 | + continue; | |
182 | + } | |
120 | 183 | } |
184 | + pthread_mutex_unlock(&mClientsLock); | |
185 | + } while (0); | |
121 | 186 | } |
122 | - return 0; | |
123 | 187 | } |
124 | 188 | |
125 | -bool SocketListener::onDataAvailable(int socket) { | |
126 | - return false; | |
189 | +void SocketListener::sendBroadcast(char *msg) { | |
190 | + pthread_mutex_lock(&mClientsLock); | |
191 | + SocketClientCollection::iterator i; | |
192 | + | |
193 | + for (i = mClients->begin(); i != mClients->end(); ++i) { | |
194 | + if ((*i)->sendMsg(msg)) { | |
195 | + LOGW("Error sending broadcast (%s)", strerror(errno)); | |
196 | + } | |
197 | + } | |
198 | + pthread_mutex_unlock(&mClientsLock); | |
199 | +} | |
200 | + | |
201 | +void SocketListener::sendBroadcast(char *msg, char *data) { | |
202 | + pthread_mutex_lock(&mClientsLock); | |
203 | + SocketClientCollection::iterator i; | |
204 | + | |
205 | + for (i = mClients->begin(); i != mClients->end(); ++i) { | |
206 | + if ((*i)->sendMsg(msg, data)) { | |
207 | + LOGW("Error sending broadcast (%s)", strerror(errno)); | |
208 | + } | |
209 | + } | |
210 | + pthread_mutex_unlock(&mClientsLock); | |
127 | 211 | } |
212 | + |