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