10175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn/* 20175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Copyright (C) 2012-2013 The Android Open Source Project 30175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * 40175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License"); 50175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * you may not use this file except in compliance with the License. 60175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * You may obtain a copy of the License at 70175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * 80175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * http://www.apache.org/licenses/LICENSE-2.0 90175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * 100175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Unless required by applicable law or agreed to in writing, software 110175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS, 120175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * See the License for the specific language governing permissions and 140175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * limitations under the License. 150175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn */ 160175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 17fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#include <ctype.h> 18fa3add33644eb0e0335fefafef41de5e2d3c0b3cMark Salyzyn#include <inttypes.h> 190175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <poll.h> 208daa9af02dc0e63ce220e3fa95bf5fe4d6b7a99aMark Salyzyn#include <sys/prctl.h> 210175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <sys/socket.h> 225c77ad55d0cdee84cd45fd5d0d066f3c61d76ce6Mark Salyzyn#include <sys/types.h> 23dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn 240175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <cutils/sockets.h> 25aeaaf81c2cc8366ac4f66eb3d2fc85f9b8194982Mark Salyzyn#include <private/android_logger.h> 260175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 270175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include "FlushCommand.h" 282ad0bd0a9b594bbe2560b405b0008b7bc742cfcaMark Salyzyn#include "LogBuffer.h" 292ad0bd0a9b594bbe2560b405b0008b7bc742cfcaMark Salyzyn#include "LogBufferElement.h" 302ad0bd0a9b594bbe2560b405b0008b7bc742cfcaMark Salyzyn#include "LogReader.h" 312ad0bd0a9b594bbe2560b405b0008b7bc742cfcaMark Salyzyn#include "LogUtils.h" 320175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 33501c373916e292764400dbae735f44b33378400fMark SalyzynLogReader::LogReader(LogBuffer* logbuf) 34501c373916e292764400dbae735f44b33378400fMark Salyzyn : SocketListener(getLogSocket(), true), mLogbuf(*logbuf) { 357718778793b106498b931dd708a466cf3a6f6a0fMark Salyzyn} 360175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 370175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// When we are notified a new log entry is available, inform 38f6e229695375bda653a7f1b6f2470e054dc2d6bfHao Wang// listening sockets who are watching this entry's log id. 39f6e229695375bda653a7f1b6f2470e054dc2d6bfHao Wangvoid LogReader::notifyNewLog(log_mask_t logMask) { 40f6e229695375bda653a7f1b6f2470e054dc2d6bfHao Wang FlushCommand command(*this, logMask); 410175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn runOnEachSocket(&command); 420175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn} 430175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 44501c373916e292764400dbae735f44b33378400fMark Salyzynbool LogReader::onDataAvailable(SocketClient* cli) { 45e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn static bool name_set; 46e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn if (!name_set) { 47e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn prctl(PR_SET_NAME, "logd.reader"); 48e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn name_set = true; 49e3aeeeeccc260c29ca5907a444f8d746bcc2f8a5Mark Salyzyn } 508daa9af02dc0e63ce220e3fa95bf5fe4d6b7a99aMark Salyzyn 510175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn char buffer[255]; 520175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 530175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn int len = read(cli->getSocket(), buffer, sizeof(buffer) - 1); 540175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (len <= 0) { 550175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn doSocketDelete(cli); 560175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return false; 570175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 580175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn buffer[len] = '\0'; 590175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 600175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn unsigned long tail = 0; 610175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn static const char _tail[] = " tail="; 62501c373916e292764400dbae735f44b33378400fMark Salyzyn char* cp = strstr(buffer, _tail); 630175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (cp) { 640175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn tail = atol(cp + sizeof(_tail) - 1); 650175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 660175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 67fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn log_time start(log_time::EPOCH); 68fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn static const char _start[] = " start="; 69fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn cp = strstr(buffer, _start); 70fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn if (cp) { 71fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn // Parse errors will result in current time 72fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn start.strptime(cp + sizeof(_start) - 1, "%s.%q"); 73fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } 74fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 75b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn uint64_t timeout = 0; 76b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn static const char _timeout[] = " timeout="; 77b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn cp = strstr(buffer, _timeout); 78b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn if (cp) { 79b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn timeout = atol(cp + sizeof(_timeout) - 1) * NS_PER_SEC + 80b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn log_time(CLOCK_REALTIME).nsec(); 81b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn } 82b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn 830175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn unsigned int logMask = -1; 840175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn static const char _logIds[] = " lids="; 850175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn cp = strstr(buffer, _logIds); 860175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (cp) { 870175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn logMask = 0; 880175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn cp += sizeof(_logIds) - 1; 890175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn while (*cp && *cp != '\0') { 900175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn int val = 0; 91fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn while (isdigit(*cp)) { 92fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn val = val * 10 + *cp - '0'; 930175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn ++cp; 940175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 950175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn logMask |= 1 << val; 960175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (*cp != ',') { 970175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn break; 980175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 990175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn ++cp; 1000175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 1010175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 1020175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 1030175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn pid_t pid = 0; 1040175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn static const char _pid[] = " pid="; 1050175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn cp = strstr(buffer, _pid); 1060175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (cp) { 1070175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn pid = atol(cp + sizeof(_pid) - 1); 1080175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 1090175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 1100175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn bool nonBlock = false; 1110eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn if (!fastcmp<strncmp>(buffer, "dumpAndClose", 12)) { 112f669acb01880216b6c1d29fc226f2c3ec3a6368aMark Salyzyn // Allow writer to get some cycles, and wait for pending notifications 113f669acb01880216b6c1d29fc226f2c3ec3a6368aMark Salyzyn sched_yield(); 1143c501b50b41086cde59a6811f4aa5cd3e736f5f2Mark Salyzyn LogTimeEntry::wrlock(); 115f669acb01880216b6c1d29fc226f2c3ec3a6368aMark Salyzyn LogTimeEntry::unlock(); 116f669acb01880216b6c1d29fc226f2c3ec3a6368aMark Salyzyn sched_yield(); 1170175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn nonBlock = true; 1180175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 1190175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 1205a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn log_time sequence = start; 1215a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // 1225a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // This somewhat expensive data validation operation is required 1235a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // for non-blocking, with timeout. The incoming timestamp must be 1245a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // in range of the list, if not, return immediately. This is 1255a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // used to prevent us from from getting stuck in timeout processing 1265a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // with an invalid time. 1275a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // 1285a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // Find if time is really present in the logs, monotonic or real, implicit 1295a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // conversion from monotonic or real as necessary to perform the check. 1305a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // Exit in the check loop ASAP as you find a transition from older to 1315a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // newer, but use the last entry found to ensure overlap. 1325a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn // 1335a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn if (nonBlock && (sequence != log_time::EPOCH) && timeout) { 1345a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn class LogFindStart { // A lambda by another name 1355a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn private: 136a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn const pid_t mPid; 137a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn const unsigned mLogMask; 1385a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn bool mStartTimeSet; 1395a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn log_time mStart; 1405a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn log_time& mSequence; 1415a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn log_time mLast; 1425a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn bool mIsMonotonic; 143a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn 144501c373916e292764400dbae735f44b33378400fMark Salyzyn public: 1455a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn LogFindStart(pid_t pid, unsigned logMask, log_time& sequence, 1465a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn bool isMonotonic) 147501c373916e292764400dbae735f44b33378400fMark Salyzyn : mPid(pid), 148501c373916e292764400dbae735f44b33378400fMark Salyzyn mLogMask(logMask), 1495a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn mStartTimeSet(false), 1505a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn mStart(sequence), 1515a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn mSequence(sequence), 1525a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn mLast(sequence), 1535a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn mIsMonotonic(isMonotonic) { 1547718778793b106498b931dd708a466cf3a6f6a0fMark Salyzyn } 155a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn 156501c373916e292764400dbae735f44b33378400fMark Salyzyn static int callback(const LogBufferElement* element, void* obj) { 157501c373916e292764400dbae735f44b33378400fMark Salyzyn LogFindStart* me = reinterpret_cast<LogFindStart*>(obj); 158501c373916e292764400dbae735f44b33378400fMark Salyzyn if ((!me->mPid || (me->mPid == element->getPid())) && 159501c373916e292764400dbae735f44b33378400fMark Salyzyn (me->mLogMask & (1 << element->getLogId()))) { 1605a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn log_time real = element->getRealTime(); 1615a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn if (me->mStart == real) { 1625a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn me->mSequence = real; 1635a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn me->mStartTimeSet = true; 164f7c0f75275d0fde2d8b7614f1501f0ad0cd3a01cMark Salyzyn return -1; 1655a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn } else if (!me->mIsMonotonic || android::isMonotonic(real)) { 1665a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn if (me->mStart < real) { 1675a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn me->mSequence = me->mLast; 1685a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn me->mStartTimeSet = true; 169f7c0f75275d0fde2d8b7614f1501f0ad0cd3a01cMark Salyzyn return -1; 170a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn } 1715a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn me->mLast = real; 172b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn } else { 1735a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn me->mLast = real; 174a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn } 175a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn } 176a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn return false; 177a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn } 178a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn 179501c373916e292764400dbae735f44b33378400fMark Salyzyn bool found() { 1805a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn return mStartTimeSet; 181501c373916e292764400dbae735f44b33378400fMark Salyzyn } 1825a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn 1835a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn } logFindStart(pid, logMask, sequence, 184b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn logbuf().isMonotonic() && android::isMonotonic(start)); 185a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn 186ae2abf112ca8555dfc09eb1fc4b8bd637e4bc7ccMark Salyzyn logbuf().flushTo(cli, sequence, nullptr, FlushCommand::hasReadLogs(cli), 1878fa8896d2ed97eb274c62f0e386dabf2e2a82a45Mark Salyzyn FlushCommand::hasSecurityLogs(cli), 188a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn logFindStart.callback, &logFindStart); 189a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn 190a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn if (!logFindStart.found()) { 1915a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn doSocketDelete(cli); 1925a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn return false; 193a1c60cf80d0d1002576a6cf8aa395b295c6a272eMark Salyzyn } 194fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } 195fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 196fa3add33644eb0e0335fefafef41de5e2d3c0b3cMark Salyzyn android::prdebug( 197fa3add33644eb0e0335fefafef41de5e2d3c0b3cMark Salyzyn "logdr: UID=%d GID=%d PID=%d %c tail=%lu logMask=%x pid=%d " 198fa3add33644eb0e0335fefafef41de5e2d3c0b3cMark Salyzyn "start=%" PRIu64 "ns timeout=%" PRIu64 "ns\n", 199fa3add33644eb0e0335fefafef41de5e2d3c0b3cMark Salyzyn cli->getUid(), cli->getGid(), cli->getPid(), nonBlock ? 'n' : 'b', tail, 200fa3add33644eb0e0335fefafef41de5e2d3c0b3cMark Salyzyn logMask, (int)pid, sequence.nsec(), timeout); 201fa3add33644eb0e0335fefafef41de5e2d3c0b3cMark Salyzyn 202b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn FlushCommand command(*this, nonBlock, tail, logMask, pid, sequence, timeout); 2035c77ad55d0cdee84cd45fd5d0d066f3c61d76ce6Mark Salyzyn 2045c77ad55d0cdee84cd45fd5d0d066f3c61d76ce6Mark Salyzyn // Set acceptable upper limit to wait for slow reader processing b/27242723 2055c77ad55d0cdee84cd45fd5d0d066f3c61d76ce6Mark Salyzyn struct timeval t = { LOGD_SNDTIMEO, 0 }; 206501c373916e292764400dbae735f44b33378400fMark Salyzyn setsockopt(cli->getSocket(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&t, 207501c373916e292764400dbae735f44b33378400fMark Salyzyn sizeof(t)); 2085c77ad55d0cdee84cd45fd5d0d066f3c61d76ce6Mark Salyzyn 2090175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn command.runSocketCommand(cli); 2100175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return true; 2110175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn} 2120175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 213501c373916e292764400dbae735f44b33378400fMark Salyzynvoid LogReader::doSocketDelete(SocketClient* cli) { 214501c373916e292764400dbae735f44b33378400fMark Salyzyn LastLogTimes& times = mLogbuf.mTimes; 2153c501b50b41086cde59a6811f4aa5cd3e736f5f2Mark Salyzyn LogTimeEntry::wrlock(); 2160175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn LastLogTimes::iterator it = times.begin(); 217501c373916e292764400dbae735f44b33378400fMark Salyzyn while (it != times.end()) { 218501c373916e292764400dbae735f44b33378400fMark Salyzyn LogTimeEntry* entry = (*it); 2190175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (entry->mClient == cli) { 2200175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn times.erase(it); 2210175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn entry->release_Locked(); 2220175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn break; 2230175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 2240175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn it++; 2250175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 2260175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn LogTimeEntry::unlock(); 2270175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn} 228dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn 229dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzynint LogReader::getLogSocket() { 230dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn static const char socketName[] = "logdr"; 231dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn int sock = android_get_control_socket(socketName); 232dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn 233dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn if (sock < 0) { 234501c373916e292764400dbae735f44b33378400fMark Salyzyn sock = socket_local_server( 235501c373916e292764400dbae735f44b33378400fMark Salyzyn socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); 236dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn } 237dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn 238dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn return sock; 239dfc47e86858ea67c72f1df2fdb97094b8e8248f2Mark Salyzyn} 240