FlushCommand.cpp revision c03e72cc1c155ff668df8df1caec363b07347d0d
1/* 2 * Copyright (C) 2012-2013 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 17#include <stdlib.h> 18#include <private/android_filesystem_config.h> 19#include "FlushCommand.h" 20#include "LogBufferElement.h" 21#include "LogTimes.h" 22#include "LogReader.h" 23 24FlushCommand::FlushCommand(LogReader &reader, 25 bool nonBlock, 26 unsigned long tail, 27 unsigned int logMask, 28 pid_t pid) 29 : mReader(reader) 30 , mNonBlock(nonBlock) 31 , mTail(tail) 32 , mLogMask(logMask) 33 , mPid(pid) 34{ } 35 36// runSocketCommand is called once for every open client on the 37// log reader socket. Here we manage and associated the reader 38// client tracking and log region locks LastLogTimes list of 39// LogTimeEntrys, and spawn a transitory per-client thread to 40// work at filing data to the socket. 41// 42// global LogTimeEntry::lock() is used to protect access, 43// reference counts are used to ensure that individual 44// LogTimeEntry lifetime is managed when not protected. 45void FlushCommand::runSocketCommand(SocketClient *client) { 46 LogTimeEntry *entry = NULL; 47 LastLogTimes × = mReader.logbuf().mTimes; 48 49 LogTimeEntry::lock(); 50 LastLogTimes::iterator it = times.begin(); 51 while(it != times.end()) { 52 entry = (*it); 53 if (entry->mClient == client) { 54 entry->triggerReader_Locked(); 55 if (entry->runningReader_Locked()) { 56 LogTimeEntry::unlock(); 57 return; 58 } 59 entry->incRef_Locked(); 60 break; 61 } 62 it++; 63 } 64 65 if (it == times.end()) { 66 // Create LogTimeEntry in notifyNewLog() ? 67 if (mTail == (unsigned long) -1) { 68 LogTimeEntry::unlock(); 69 return; 70 } 71 entry = new LogTimeEntry(mReader, client, mNonBlock, mTail, mLogMask, mPid); 72 times.push_back(entry); 73 } 74 75 client->incRef(); 76 77 // release client and entry reference counts once done 78 entry->startReader_Locked(); 79 LogTimeEntry::unlock(); 80} 81 82bool FlushCommand::hasReadLogs(SocketClient *client) { 83 return (client->getUid() == AID_ROOT) 84 || (client->getGid() == AID_ROOT) 85 || (client->getGid() == AID_LOG); 86} 87