diff options
author | Mark Salyzyn <salyzyn@google.com> | 2014-01-28 21:20:39 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-01-28 21:20:39 +0000 |
commit | 3a5f3050626c01c45ff487274a2399876d63a4eb (patch) | |
tree | bbb790426c99ffae28119611ac3a4955c169461e /libsysutils/src | |
parent | f286938177390ec058ea39b308c9b9498b011c7c (diff) | |
parent | 7b9bb36ade6c8fa2e77416143847b019ddda9e95 (diff) | |
download | system_core-3a5f3050626c01c45ff487274a2399876d63a4eb.zip system_core-3a5f3050626c01c45ff487274a2399876d63a4eb.tar.gz system_core-3a5f3050626c01c45ff487274a2399876d63a4eb.tar.bz2 |
am 7b9bb36a: am 0256e1f6: am d2acdd82: Merge changes I70ab37d5,I716f89c0,I34c96adf,I77650923,I35b0d1ee, ...
* commit '7b9bb36ade6c8fa2e77416143847b019ddda9e95': (29 commits)
libsysutils: SocketListener export release
libsysutils: Add iovec/runOnEachSocket
liblog: support struct logger_event_v2 format
liblog: update timestamp on NOTICE file
libcutils: resolve warning in iosched_policy.c
liblog: Add const pedantics
logcat: Add -T flag (-t w/o assumption of -d)
logcat: Add logcat test suite
liblog: Add cpu utilization test
liblog: Add liblog test suite
debuggerd: Support newline split in log messages
liblog: deprecate export LOGGER ioctl definitions
liblog: deprecate export of LOGGER_LOG_* defines
liblog: Add README
liblog: resolve build warning messages
liblog: high CPU usage from logcat
liblog: fix build again
liblog: drop use of sys/cdefs.h
liblog: git_master@964770 build problem
logcat: Incorporate liblog reading API
...
Diffstat (limited to 'libsysutils/src')
-rw-r--r-- | libsysutils/src/FrameworkCommand.cpp | 5 | ||||
-rw-r--r-- | libsysutils/src/FrameworkListener.cpp | 4 | ||||
-rw-r--r-- | libsysutils/src/SocketClient.cpp | 59 | ||||
-rw-r--r-- | libsysutils/src/SocketListener.cpp | 127 |
4 files changed, 144 insertions, 51 deletions
diff --git a/libsysutils/src/FrameworkCommand.cpp b/libsysutils/src/FrameworkCommand.cpp index 038d87e..0b95a81 100644 --- a/libsysutils/src/FrameworkCommand.cpp +++ b/libsysutils/src/FrameworkCommand.cpp @@ -21,11 +21,14 @@ #include <sysutils/FrameworkCommand.h> +#define UNUSED __attribute__((unused)) + FrameworkCommand::FrameworkCommand(const char *cmd) { mCommand = cmd; } -int FrameworkCommand::runCommand(SocketClient *c, int argc, char **argv) { +int FrameworkCommand::runCommand(SocketClient *c UNUSED, int argc UNUSED, + char **argv UNUSED) { SLOGW("Command %s has no run handler!", getCommand()); errno = ENOSYS; return -1; diff --git a/libsysutils/src/FrameworkListener.cpp b/libsysutils/src/FrameworkListener.cpp index 02a401d..a5ffda2 100644 --- a/libsysutils/src/FrameworkListener.cpp +++ b/libsysutils/src/FrameworkListener.cpp @@ -27,6 +27,8 @@ static const int CMD_BUF_SIZE = 1024; +#define UNUSED __attribute__((unused)) + FrameworkListener::FrameworkListener(const char *socketName, bool withSeq) : SocketListener(socketName, true, withSeq) { init(socketName, withSeq); @@ -37,7 +39,7 @@ FrameworkListener::FrameworkListener(const char *socketName) : init(socketName, false); } -void FrameworkListener::init(const char *socketName, bool withSeq) { +void FrameworkListener::init(const char *socketName UNUSED, bool withSeq) { mCommands = new FrameworkCommandCollection(); errorRate = 0; mCommandCount = 0; diff --git a/libsysutils/src/SocketClient.cpp b/libsysutils/src/SocketClient.cpp index ae0e077..3625d93 100644 --- a/libsysutils/src/SocketClient.cpp +++ b/libsysutils/src/SocketClient.cpp @@ -71,7 +71,7 @@ int SocketClient::sendMsg(int code, const char *msg, bool addErrno, bool useCmdN ret = asprintf(&buf, "%d %s", code, msg); } } - /* Send the zero-terminated message */ + // Send the zero-terminated message if (ret != -1) { ret = sendMsg(buf); free(buf); @@ -79,22 +79,25 @@ int SocketClient::sendMsg(int code, const char *msg, bool addErrno, bool useCmdN return ret; } -/** send 3-digit code, null, binary-length, binary data */ +// send 3-digit code, null, binary-length, binary data int SocketClient::sendBinaryMsg(int code, const void *data, int len) { - /* 4 bytes for the code & null + 4 bytes for the len */ + // 4 bytes for the code & null + 4 bytes for the len char buf[8]; - /* Write the code */ + // Write the code snprintf(buf, 4, "%.3d", code); - /* Write the len */ + // Write the len uint32_t tmp = htonl(len); memcpy(buf + 4, &tmp, sizeof(uint32_t)); + struct iovec vec[2]; + vec[0].iov_base = (void *) buf; + vec[0].iov_len = sizeof(buf); + vec[1].iov_base = (void *) data; + vec[1].iov_len = len; + pthread_mutex_lock(&mWriteMutex); - int result = sendDataLocked(buf, sizeof(buf)); - if (result == 0 && len > 0) { - result = sendDataLocked(data, len); - } + int result = sendDataLockedv(vec, (len > 0) ? 2 : 1); pthread_mutex_unlock(&mWriteMutex); return result; @@ -147,33 +150,51 @@ int SocketClient::sendMsg(const char *msg) { } int SocketClient::sendData(const void *data, int len) { + struct iovec vec[1]; + vec[0].iov_base = (void *) data; + vec[0].iov_len = len; pthread_mutex_lock(&mWriteMutex); - int rc = sendDataLocked(data, len); + int rc = sendDataLockedv(vec, 1); pthread_mutex_unlock(&mWriteMutex); return rc; } -int SocketClient::sendDataLocked(const void *data, int len) { - int rc = 0; - const char *p = (const char*) data; - int brtw = len; +int SocketClient::sendDatav(struct iovec *iov, int iovcnt) { + pthread_mutex_lock(&mWriteMutex); + int rc = sendDataLockedv(iov, iovcnt); + pthread_mutex_unlock(&mWriteMutex); + + return rc; +} + +int SocketClient::sendDataLockedv(struct iovec *iov, int iovcnt) { if (mSocket < 0) { errno = EHOSTUNREACH; return -1; } - if (len == 0) { + if (iovcnt <= 0) { return 0; } - while (brtw > 0) { - rc = send(mSocket, p, brtw, MSG_NOSIGNAL); + int current = 0; + + for (;;) { + ssize_t rc = writev(mSocket, iov + current, iovcnt - current); if (rc > 0) { - p += rc; - brtw -= rc; + size_t written = rc; + while ((current < iovcnt) && (written >= iov[current].iov_len)) { + written -= iov[current].iov_len; + current++; + } + if (current == iovcnt) { + break; + } + iov[current].iov_base = (char *)iov[current].iov_base + written; + iov[current].iov_len -= written; continue; } diff --git a/libsysutils/src/SocketListener.cpp b/libsysutils/src/SocketListener.cpp index 0361641..5c75206 100644 --- a/libsysutils/src/SocketListener.cpp +++ b/libsysutils/src/SocketListener.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2008-2014 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. @@ -29,7 +29,8 @@ #include <sysutils/SocketListener.h> #include <sysutils/SocketClient.h> -#define LOG_NDEBUG 0 +#define CtrlPipe_Shutdown 0 +#define CtrlPipe_Wakeup 1 SocketListener::SocketListener(const char *socketName, bool listen) { init(socketName, -1, listen, false); @@ -103,7 +104,7 @@ int SocketListener::startListener() { } int SocketListener::stopListener() { - char c = 0; + char c = CtrlPipe_Shutdown; int rc; rc = TEMP_FAILURE_RETRY(write(mCtrlPipe[1], &c, 1)); @@ -145,7 +146,7 @@ void *SocketListener::threadStart(void *obj) { void SocketListener::runListener() { - SocketClientCollection *pendingList = new SocketClientCollection(); + SocketClientCollection pendingList; while(1) { SocketClientCollection::iterator it; @@ -166,10 +167,12 @@ void SocketListener::runListener() { pthread_mutex_lock(&mClientsLock); for (it = mClients->begin(); it != mClients->end(); ++it) { + // NB: calling out to an other object with mClientsLock held (safe) int fd = (*it)->getSocket(); FD_SET(fd, &read_fds); - if (fd > max) + if (fd > max) { max = fd; + } } pthread_mutex_unlock(&mClientsLock); SLOGV("mListen=%d, max=%d, mSocketName=%s", mListen, max, mSocketName); @@ -182,8 +185,14 @@ void SocketListener::runListener() { } else if (!rc) continue; - if (FD_ISSET(mCtrlPipe[0], &read_fds)) - break; + if (FD_ISSET(mCtrlPipe[0], &read_fds)) { + char c = CtrlPipe_Shutdown; + TEMP_FAILURE_RETRY(read(mCtrlPipe[0], &c, 1)); + if (c == CtrlPipe_Shutdown) { + break; + } + continue; + } if (mListen && FD_ISSET(mSock, &read_fds)) { struct sockaddr addr; socklen_t alen; @@ -205,53 +214,111 @@ void SocketListener::runListener() { } /* Add all active clients to the pending list first */ - pendingList->clear(); + pendingList.clear(); pthread_mutex_lock(&mClientsLock); for (it = mClients->begin(); it != mClients->end(); ++it) { - int fd = (*it)->getSocket(); + SocketClient* c = *it; + // NB: calling out to an other object with mClientsLock held (safe) + int fd = c->getSocket(); if (FD_ISSET(fd, &read_fds)) { - pendingList->push_back(*it); + pendingList.push_back(c); + c->incRef(); } } pthread_mutex_unlock(&mClientsLock); /* Process the pending list, since it is owned by the thread, * there is no need to lock it */ - while (!pendingList->empty()) { + while (!pendingList.empty()) { /* Pop the first item from the list */ - it = pendingList->begin(); + it = pendingList.begin(); SocketClient* c = *it; - pendingList->erase(it); - /* Process it, if false is returned and our sockets are - * 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) { - mClients->erase(it); - break; - } - } - pthread_mutex_unlock(&mClientsLock); - /* Remove our reference to the client */ - c->decRef(); + pendingList.erase(it); + /* Process it, if false is returned, remove from list */ + if (!onDataAvailable(c)) { + release(c, false); } + c->decRef(); } } - delete pendingList; +} + +bool SocketListener::release(SocketClient* c, bool wakeup) { + bool ret = false; + /* if our sockets are connection-based, remove and destroy it */ + if (mListen && c) { + /* Remove the client from our array */ + SLOGV("going to zap %d for %s", c->getSocket(), mSocketName); + pthread_mutex_lock(&mClientsLock); + SocketClientCollection::iterator it; + for (it = mClients->begin(); it != mClients->end(); ++it) { + if (*it == c) { + mClients->erase(it); + ret = true; + break; + } + } + pthread_mutex_unlock(&mClientsLock); + if (ret) { + ret = c->decRef(); + if (wakeup) { + char b = CtrlPipe_Wakeup; + TEMP_FAILURE_RETRY(write(mCtrlPipe[1], &b, 1)); + } + } + } + return ret; } void SocketListener::sendBroadcast(int code, const char *msg, bool addErrno) { + SocketClientCollection safeList; + + /* Add all active clients to the safe list first */ + safeList.clear(); pthread_mutex_lock(&mClientsLock); SocketClientCollection::iterator i; for (i = mClients->begin(); i != mClients->end(); ++i) { + SocketClient* c = *i; + c->incRef(); + safeList.push_back(c); + } + pthread_mutex_unlock(&mClientsLock); + + while (!safeList.empty()) { + /* Pop the first item from the list */ + i = safeList.begin(); + SocketClient* c = *i; + safeList.erase(i); // broadcasts are unsolicited and should not include a cmd number - if ((*i)->sendMsg(code, msg, addErrno, false)) { + if (c->sendMsg(code, msg, addErrno, false)) { SLOGW("Error sending broadcast (%s)", strerror(errno)); } + c->decRef(); + } +} + +void SocketListener::runOnEachSocket(SocketClientCommand *command) { + SocketClientCollection safeList; + + /* Add all active clients to the safe list first */ + safeList.clear(); + pthread_mutex_lock(&mClientsLock); + SocketClientCollection::iterator i; + + for (i = mClients->begin(); i != mClients->end(); ++i) { + SocketClient* c = *i; + c->incRef(); + safeList.push_back(c); } pthread_mutex_unlock(&mClientsLock); + + while (!safeList.empty()) { + /* Pop the first item from the list */ + i = safeList.begin(); + SocketClient* c = *i; + safeList.erase(i); + command->runSocketCommand(c); + c->decRef(); + } } |