Merge "New NativeDaemonConnector protocol adds a seqnum."
This commit is contained in:
commit
78f6bcf853
|
@ -24,11 +24,17 @@ class SocketClient;
|
|||
class FrameworkListener : public SocketListener {
|
||||
public:
|
||||
static const int CMD_ARGS_MAX = 16;
|
||||
|
||||
/* 1 out of errorRate will be dropped */
|
||||
int errorRate;
|
||||
private:
|
||||
int mCommandCount;
|
||||
bool mWithSeq;
|
||||
FrameworkCommandCollection *mCommands;
|
||||
|
||||
public:
|
||||
FrameworkListener(const char *socketName);
|
||||
FrameworkListener(const char *socketName, bool withSeq);
|
||||
virtual ~FrameworkListener() {}
|
||||
|
||||
protected:
|
||||
|
@ -37,5 +43,6 @@ protected:
|
|||
|
||||
private:
|
||||
void dispatchCommand(SocketClient *c, char *data);
|
||||
void init(const char *socketName, bool withSeq);
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "List.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <cutils/atomic.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
class SocketClient {
|
||||
|
@ -24,20 +25,27 @@ class SocketClient {
|
|||
pthread_mutex_t mRefCountMutex;
|
||||
int mRefCount;
|
||||
|
||||
int mCmdNum;
|
||||
|
||||
bool mUseCmdNum;
|
||||
|
||||
public:
|
||||
SocketClient(int sock, bool owned);
|
||||
SocketClient(int sock, bool owned, bool useCmdNum);
|
||||
virtual ~SocketClient();
|
||||
|
||||
int getSocket() { return mSocket; }
|
||||
pid_t getPid() const { return mPid; }
|
||||
uid_t getUid() const { return mUid; }
|
||||
gid_t getGid() const { return mGid; }
|
||||
void setCmdNum(int cmdNum) { android_atomic_release_store(cmdNum, &mCmdNum); }
|
||||
int getCmdNum() { return mCmdNum; }
|
||||
|
||||
// Send null-terminated C strings:
|
||||
int sendMsg(int code, const char *msg, bool addErrno);
|
||||
int sendMsg(const char *msg);
|
||||
int sendMsg(int code, const char *msg, bool addErrno, bool useCmdNum);
|
||||
|
||||
// Sending binary data:
|
||||
//Sending binary data:
|
||||
int sendData(const void *data, int len);
|
||||
|
||||
// Optional reference counting. Reference count starts at 1. If
|
||||
|
@ -46,6 +54,11 @@ public:
|
|||
// decRef() when it's done with the client.
|
||||
void incRef();
|
||||
bool decRef(); // returns true at 0 (but note: SocketClient already deleted)
|
||||
|
||||
private:
|
||||
// Send null-terminated C strings
|
||||
int sendMsg(const char *msg);
|
||||
void init(int socket, bool owned, bool useCmdNum);
|
||||
};
|
||||
|
||||
typedef android::sysutils::List<SocketClient *> SocketClientCollection;
|
||||
|
|
|
@ -21,16 +21,18 @@
|
|||
#include <sysutils/SocketClient.h>
|
||||
|
||||
class SocketListener {
|
||||
int mSock;
|
||||
bool mListen;
|
||||
const char *mSocketName;
|
||||
int mSock;
|
||||
SocketClientCollection *mClients;
|
||||
pthread_mutex_t mClientsLock;
|
||||
bool mListen;
|
||||
int mCtrlPipe[2];
|
||||
pthread_t mThread;
|
||||
bool mUseCmdNum;
|
||||
|
||||
public:
|
||||
SocketListener(const char *socketName, bool listen);
|
||||
SocketListener(const char *socketName, bool listen, bool useCmdNum);
|
||||
SocketListener(int socketFd, bool listen);
|
||||
|
||||
virtual ~SocketListener();
|
||||
|
@ -38,7 +40,6 @@ public:
|
|||
int stopListener();
|
||||
|
||||
void sendBroadcast(int code, const char *msg, bool addErrno);
|
||||
void sendBroadcast(const char *msg);
|
||||
|
||||
protected:
|
||||
virtual bool onDataAvailable(SocketClient *c) = 0;
|
||||
|
@ -46,5 +47,6 @@ protected:
|
|||
private:
|
||||
static void *threadStart(void *obj);
|
||||
void runListener();
|
||||
void init(const char *socketName, int socketFd, bool listen, bool useCmdNum);
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -25,9 +25,21 @@
|
|||
#include <sysutils/FrameworkCommand.h>
|
||||
#include <sysutils/SocketClient.h>
|
||||
|
||||
FrameworkListener::FrameworkListener(const char *socketName, bool withSeq) :
|
||||
SocketListener(socketName, true, withSeq) {
|
||||
init(socketName, withSeq);
|
||||
}
|
||||
|
||||
FrameworkListener::FrameworkListener(const char *socketName) :
|
||||
SocketListener(socketName, true) {
|
||||
SocketListener(socketName, true, false) {
|
||||
init(socketName, false);
|
||||
}
|
||||
|
||||
void FrameworkListener::init(const char *socketName, bool withSeq) {
|
||||
mCommands = new FrameworkCommandCollection();
|
||||
errorRate = 0;
|
||||
mCommandCount = 0;
|
||||
mWithSeq = withSeq;
|
||||
}
|
||||
|
||||
bool FrameworkListener::onDataAvailable(SocketClient *c) {
|
||||
|
@ -69,6 +81,7 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
|
|||
bool esc = false;
|
||||
bool quote = false;
|
||||
int k;
|
||||
bool haveCmdNum = !mWithSeq;
|
||||
|
||||
memset(argv, 0, sizeof(argv));
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
|
@ -115,9 +128,20 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
|
|||
*q = *p++;
|
||||
if (!quote && *q == ' ') {
|
||||
*q = '\0';
|
||||
if (argc >= CMD_ARGS_MAX)
|
||||
goto overflow;
|
||||
argv[argc++] = strdup(tmp);
|
||||
if (!haveCmdNum) {
|
||||
char *endptr;
|
||||
int cmdNum = (int)strtol(tmp, &endptr, 0);
|
||||
if (endptr == NULL || *endptr != '\0') {
|
||||
cli->sendMsg(500, "Invalid sequence number", false);
|
||||
goto out;
|
||||
}
|
||||
cli->setCmdNum(cmdNum);
|
||||
haveCmdNum = true;
|
||||
} else {
|
||||
if (argc >= CMD_ARGS_MAX)
|
||||
goto overflow;
|
||||
argv[argc++] = strdup(tmp);
|
||||
}
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
q = tmp;
|
||||
continue;
|
||||
|
@ -140,6 +164,12 @@ void FrameworkListener::dispatchCommand(SocketClient *cli, char *data) {
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (errorRate && (++mCommandCount % errorRate == 0)) {
|
||||
/* ignore this command - let the timeout handler handle it */
|
||||
SLOGE("Faking a timeout");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = mCommands->begin(); i != mCommands->end(); ++i) {
|
||||
FrameworkCommand *c = *i;
|
||||
|
||||
|
|
|
@ -10,16 +10,25 @@
|
|||
|
||||
#include <sysutils/SocketClient.h>
|
||||
|
||||
SocketClient::SocketClient(int socket, bool owned)
|
||||
: mSocket(socket)
|
||||
, mSocketOwned(owned)
|
||||
, mPid(-1)
|
||||
, mUid(-1)
|
||||
, mGid(-1)
|
||||
, mRefCount(1)
|
||||
{
|
||||
SocketClient::SocketClient(int socket, bool owned) {
|
||||
init(socket, owned, false);
|
||||
}
|
||||
|
||||
SocketClient::SocketClient(int socket, bool owned, bool useCmdNum) {
|
||||
init(socket, owned, useCmdNum);
|
||||
}
|
||||
|
||||
void SocketClient::init(int socket, bool owned, bool useCmdNum) {
|
||||
mSocket = socket;
|
||||
mSocketOwned = owned;
|
||||
mUseCmdNum = useCmdNum;
|
||||
pthread_mutex_init(&mWriteMutex, NULL);
|
||||
pthread_mutex_init(&mRefCountMutex, NULL);
|
||||
mPid = -1;
|
||||
mUid = -1;
|
||||
mGid = -1;
|
||||
mRefCount = 1;
|
||||
mCmdNum = 0;
|
||||
|
||||
struct ucred creds;
|
||||
socklen_t szCreds = sizeof(creds);
|
||||
|
@ -41,26 +50,32 @@ SocketClient::~SocketClient()
|
|||
}
|
||||
|
||||
int SocketClient::sendMsg(int code, const char *msg, bool addErrno) {
|
||||
return sendMsg(code, msg, addErrno, mUseCmdNum);
|
||||
}
|
||||
|
||||
int SocketClient::sendMsg(int code, const char *msg, bool addErrno, bool useCmdNum) {
|
||||
char *buf;
|
||||
const char* arg;
|
||||
const char* fmt;
|
||||
char tmp[1];
|
||||
int len;
|
||||
int ret = 0;
|
||||
|
||||
if (addErrno) {
|
||||
fmt = "%.3d %s (%s)";
|
||||
arg = strerror(errno);
|
||||
if (useCmdNum) {
|
||||
ret = asprintf(&buf, "%d %d %s (%s)", code, getCmdNum(), msg, strerror(errno));
|
||||
} else {
|
||||
ret = asprintf(&buf, "%d %s (%s)", code, msg, strerror(errno));
|
||||
}
|
||||
} else {
|
||||
fmt = "%.3d %s";
|
||||
arg = NULL;
|
||||
if (useCmdNum) {
|
||||
ret = asprintf(&buf, "%d %d %s", code, getCmdNum(), msg);
|
||||
} else {
|
||||
ret = asprintf(&buf, "%d %s", code, msg);
|
||||
}
|
||||
}
|
||||
/* Measure length of required buffer */
|
||||
len = snprintf(tmp, sizeof tmp, fmt, code, msg, arg);
|
||||
/* Allocate in the stack, then write to it */
|
||||
buf = (char*)alloca(len+1);
|
||||
snprintf(buf, len+1, fmt, code, msg, arg);
|
||||
/* Send the zero-terminated message */
|
||||
return sendMsg(buf);
|
||||
if (ret != -1) {
|
||||
ret = sendMsg(buf);
|
||||
free(buf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SocketClient::sendMsg(const char *msg) {
|
||||
|
|
|
@ -29,18 +29,25 @@
|
|||
#include <sysutils/SocketListener.h>
|
||||
#include <sysutils/SocketClient.h>
|
||||
|
||||
#define LOG_NDEBUG 0
|
||||
|
||||
SocketListener::SocketListener(const char *socketName, bool listen) {
|
||||
mListen = listen;
|
||||
mSocketName = socketName;
|
||||
mSock = -1;
|
||||
pthread_mutex_init(&mClientsLock, NULL);
|
||||
mClients = new SocketClientCollection();
|
||||
init(socketName, -1, listen, false);
|
||||
}
|
||||
|
||||
SocketListener::SocketListener(int socketFd, bool listen) {
|
||||
init(NULL, socketFd, listen, false);
|
||||
}
|
||||
|
||||
SocketListener::SocketListener(const char *socketName, bool listen, bool useCmdNum) {
|
||||
init(socketName, -1, listen, useCmdNum);
|
||||
}
|
||||
|
||||
void SocketListener::init(const char *socketName, int socketFd, bool listen, bool useCmdNum) {
|
||||
mListen = listen;
|
||||
mSocketName = NULL;
|
||||
mSocketName = socketName;
|
||||
mSock = socketFd;
|
||||
mUseCmdNum = useCmdNum;
|
||||
pthread_mutex_init(&mClientsLock, NULL);
|
||||
mClients = new SocketClientCollection();
|
||||
}
|
||||
|
@ -73,13 +80,14 @@ int SocketListener::startListener() {
|
|||
mSocketName, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
SLOGV("got mSock = %d for %s", mSock, mSocketName);
|
||||
}
|
||||
|
||||
if (mListen && listen(mSock, 4) < 0) {
|
||||
SLOGE("Unable to listen on socket (%s)", strerror(errno));
|
||||
return -1;
|
||||
} else if (!mListen)
|
||||
mClients->push_back(new SocketClient(mSock, false));
|
||||
mClients->push_back(new SocketClient(mSock, false, mUseCmdNum));
|
||||
|
||||
if (pipe(mCtrlPipe)) {
|
||||
SLOGE("pipe failed (%s)", strerror(errno));
|
||||
|
@ -164,11 +172,11 @@ void SocketListener::runListener() {
|
|||
max = fd;
|
||||
}
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
|
||||
SLOGV("mListen=%d, max=%d, mSocketName=%s", mListen, max, mSocketName);
|
||||
if ((rc = select(max + 1, &read_fds, NULL, NULL, NULL)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
SLOGE("select failed (%s)", strerror(errno));
|
||||
SLOGE("select failed (%s) mListen=%d, max=%d", strerror(errno), mListen, max);
|
||||
sleep(1);
|
||||
continue;
|
||||
} else if (!rc)
|
||||
|
@ -184,6 +192,7 @@ void SocketListener::runListener() {
|
|||
do {
|
||||
alen = sizeof(addr);
|
||||
c = accept(mSock, &addr, &alen);
|
||||
SLOGV("%s got %d from accept", mSocketName, c);
|
||||
} while (c < 0 && errno == EINTR);
|
||||
if (c < 0) {
|
||||
SLOGE("accept failed (%s)", strerror(errno));
|
||||
|
@ -191,7 +200,7 @@ void SocketListener::runListener() {
|
|||
continue;
|
||||
}
|
||||
pthread_mutex_lock(&mClientsLock);
|
||||
mClients->push_back(new SocketClient(c, true));
|
||||
mClients->push_back(new SocketClient(c, true, mUseCmdNum));
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
}
|
||||
|
||||
|
@ -217,6 +226,7 @@ void SocketListener::runListener() {
|
|||
* connection-based, remove and destroy it */
|
||||
if (!onDataAvailable(c) && mListen) {
|
||||
/* Remove the client from our array */
|
||||
SLOGV("going to zap %d for %s", c->getSocket(), mSocketName);
|
||||
pthread_mutex_lock(&mClientsLock);
|
||||
for (it = mClients->begin(); it != mClients->end(); ++it) {
|
||||
if (*it == c) {
|
||||
|
@ -238,19 +248,8 @@ void SocketListener::sendBroadcast(int code, const char *msg, bool addErrno) {
|
|||
SocketClientCollection::iterator i;
|
||||
|
||||
for (i = mClients->begin(); i != mClients->end(); ++i) {
|
||||
if ((*i)->sendMsg(code, msg, addErrno)) {
|
||||
SLOGW("Error sending broadcast (%s)", strerror(errno));
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&mClientsLock);
|
||||
}
|
||||
|
||||
void SocketListener::sendBroadcast(const char *msg) {
|
||||
pthread_mutex_lock(&mClientsLock);
|
||||
SocketClientCollection::iterator i;
|
||||
|
||||
for (i = mClients->begin(); i != mClients->end(); ++i) {
|
||||
if ((*i)->sendMsg(msg)) {
|
||||
// broadcasts are unsolicited and should not include a cmd number
|
||||
if ((*i)->sendMsg(code, msg, addErrno, false)) {
|
||||
SLOGW("Error sending broadcast (%s)", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue