1*598139dcSAndroid Build Coastguard Worker /* 2*598139dcSAndroid Build Coastguard Worker * Copyright (C) 2012-2013 The Android Open Source Project 3*598139dcSAndroid Build Coastguard Worker * 4*598139dcSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*598139dcSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*598139dcSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*598139dcSAndroid Build Coastguard Worker * 8*598139dcSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*598139dcSAndroid Build Coastguard Worker * 10*598139dcSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*598139dcSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*598139dcSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*598139dcSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*598139dcSAndroid Build Coastguard Worker * limitations under the License. 15*598139dcSAndroid Build Coastguard Worker */ 16*598139dcSAndroid Build Coastguard Worker 17*598139dcSAndroid Build Coastguard Worker #pragma once 18*598139dcSAndroid Build Coastguard Worker 19*598139dcSAndroid Build Coastguard Worker #include <pthread.h> 20*598139dcSAndroid Build Coastguard Worker #include <sys/socket.h> 21*598139dcSAndroid Build Coastguard Worker #include <sys/types.h> 22*598139dcSAndroid Build Coastguard Worker #include <time.h> 23*598139dcSAndroid Build Coastguard Worker 24*598139dcSAndroid Build Coastguard Worker #include <chrono> 25*598139dcSAndroid Build Coastguard Worker #include <condition_variable> 26*598139dcSAndroid Build Coastguard Worker #include <list> 27*598139dcSAndroid Build Coastguard Worker #include <memory> 28*598139dcSAndroid Build Coastguard Worker 29*598139dcSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h> 30*598139dcSAndroid Build Coastguard Worker #include <log/log.h> 31*598139dcSAndroid Build Coastguard Worker 32*598139dcSAndroid Build Coastguard Worker #include "LogBuffer.h" 33*598139dcSAndroid Build Coastguard Worker #include "LogWriter.h" 34*598139dcSAndroid Build Coastguard Worker #include "LogdLock.h" 35*598139dcSAndroid Build Coastguard Worker 36*598139dcSAndroid Build Coastguard Worker struct PendingReaderThreadKey { 37*598139dcSAndroid Build Coastguard Worker uid_t uid; 38*598139dcSAndroid Build Coastguard Worker gid_t gid; 39*598139dcSAndroid Build Coastguard Worker pid_t pid; 40*598139dcSAndroid Build Coastguard Worker int32_t fd; 41*598139dcSAndroid Build Coastguard Worker bool operator==(const PendingReaderThreadKey& rhs) const { 42*598139dcSAndroid Build Coastguard Worker return uid == rhs.uid && gid == rhs.gid && pid == rhs.pid && fd == rhs.fd; 43*598139dcSAndroid Build Coastguard Worker } 44*598139dcSAndroid Build Coastguard Worker }; 45*598139dcSAndroid Build Coastguard Worker 46*598139dcSAndroid Build Coastguard Worker class LogReaderList; 47*598139dcSAndroid Build Coastguard Worker 48*598139dcSAndroid Build Coastguard Worker class LogReaderThread { 49*598139dcSAndroid Build Coastguard Worker public: 50*598139dcSAndroid Build Coastguard Worker LogReaderThread(LogBuffer* log_buffer, LogReaderList* reader_list, 51*598139dcSAndroid Build Coastguard Worker std::unique_ptr<LogWriter> writer, bool non_block, unsigned long tail, 52*598139dcSAndroid Build Coastguard Worker LogMask log_mask, pid_t pid, log_time start_time, uint64_t sequence, 53*598139dcSAndroid Build Coastguard Worker std::chrono::steady_clock::time_point deadline); TriggerReader()54*598139dcSAndroid Build Coastguard Worker void TriggerReader() REQUIRES(logd_lock) { thread_triggered_condition_.notify_all(); } 55*598139dcSAndroid Build Coastguard Worker TriggerSkip(log_id_t id,unsigned int skip)56*598139dcSAndroid Build Coastguard Worker void TriggerSkip(log_id_t id, unsigned int skip) REQUIRES(logd_lock) { skip_ahead_[id] = skip; } CleanSkip()57*598139dcSAndroid Build Coastguard Worker void CleanSkip() REQUIRES(logd_lock) { memset(skip_ahead_, 0, sizeof(skip_ahead_)); } 58*598139dcSAndroid Build Coastguard Worker 59*598139dcSAndroid Build Coastguard Worker void Run() REQUIRES(logd_lock); Revoke()60*598139dcSAndroid Build Coastguard Worker void Revoke() REQUIRES(logd_lock) { writer_->revoke(); } Release()61*598139dcSAndroid Build Coastguard Worker void Release() REQUIRES(logd_lock) { 62*598139dcSAndroid Build Coastguard Worker // gracefully shut down the socket. 63*598139dcSAndroid Build Coastguard Worker writer_->Shutdown(); 64*598139dcSAndroid Build Coastguard Worker release_ = true; 65*598139dcSAndroid Build Coastguard Worker thread_triggered_condition_.notify_all(); 66*598139dcSAndroid Build Coastguard Worker } 67*598139dcSAndroid Build Coastguard Worker IsWatching(log_id_t id)68*598139dcSAndroid Build Coastguard Worker bool IsWatching(log_id_t id) const REQUIRES(logd_lock) { 69*598139dcSAndroid Build Coastguard Worker return flush_to_state_->log_mask() & (1 << id); 70*598139dcSAndroid Build Coastguard Worker } IsWatchingMultiple(LogMask log_mask)71*598139dcSAndroid Build Coastguard Worker bool IsWatchingMultiple(LogMask log_mask) const REQUIRES(logd_lock) { 72*598139dcSAndroid Build Coastguard Worker return flush_to_state_->log_mask() & log_mask; 73*598139dcSAndroid Build Coastguard Worker } 74*598139dcSAndroid Build Coastguard Worker name()75*598139dcSAndroid Build Coastguard Worker std::string name() const REQUIRES(logd_lock) { return writer_->name(); } start()76*598139dcSAndroid Build Coastguard Worker uint64_t start() const REQUIRES(logd_lock) { return flush_to_state_->start(); } deadline()77*598139dcSAndroid Build Coastguard Worker std::chrono::steady_clock::time_point deadline() const REQUIRES(logd_lock) { return deadline_; } flush_to_state()78*598139dcSAndroid Build Coastguard Worker FlushToState& flush_to_state() REQUIRES(logd_lock) { return *flush_to_state_; } set_pending_reader_thread_key(uid_t uid,gid_t gid,pid_t pid,int32_t fd)79*598139dcSAndroid Build Coastguard Worker void set_pending_reader_thread_key(uid_t uid, gid_t gid, pid_t pid, int32_t fd) 80*598139dcSAndroid Build Coastguard Worker REQUIRES(logd_lock) { 81*598139dcSAndroid Build Coastguard Worker pending_reader_thread_key_ = {uid, gid, pid, fd}; 82*598139dcSAndroid Build Coastguard Worker } pending_reader_thread_key()83*598139dcSAndroid Build Coastguard Worker const PendingReaderThreadKey& pending_reader_thread_key() const REQUIRES(logd_lock) { 84*598139dcSAndroid Build Coastguard Worker return pending_reader_thread_key_; 85*598139dcSAndroid Build Coastguard Worker } set_finish_flag()86*598139dcSAndroid Build Coastguard Worker void set_finish_flag() REQUIRES(logd_lock) { finished_ = true; } finish_flag()87*598139dcSAndroid Build Coastguard Worker bool finish_flag() REQUIRES(logd_lock) { return finished_; } set_track_flag()88*598139dcSAndroid Build Coastguard Worker void set_track_flag() REQUIRES(logd_lock) { tracked_ = true; } track_flag()89*598139dcSAndroid Build Coastguard Worker bool track_flag() REQUIRES(logd_lock) { return tracked_; } 90*598139dcSAndroid Build Coastguard Worker 91*598139dcSAndroid Build Coastguard Worker private: 92*598139dcSAndroid Build Coastguard Worker void ThreadFunction(); 93*598139dcSAndroid Build Coastguard Worker // flushTo filter callbacks 94*598139dcSAndroid Build Coastguard Worker FilterResult FilterFirstPass(log_id_t log_id, pid_t pid, uint64_t sequence, log_time realtime) 95*598139dcSAndroid Build Coastguard Worker REQUIRES(logd_lock); 96*598139dcSAndroid Build Coastguard Worker FilterResult FilterSecondPass(log_id_t log_id, pid_t pid, uint64_t sequence, log_time realtime) 97*598139dcSAndroid Build Coastguard Worker REQUIRES(logd_lock); 98*598139dcSAndroid Build Coastguard Worker 99*598139dcSAndroid Build Coastguard Worker std::condition_variable thread_triggered_condition_; 100*598139dcSAndroid Build Coastguard Worker LogBuffer* log_buffer_; 101*598139dcSAndroid Build Coastguard Worker LogReaderList* reader_list_; 102*598139dcSAndroid Build Coastguard Worker std::unique_ptr<LogWriter> writer_ GUARDED_BY(logd_lock); 103*598139dcSAndroid Build Coastguard Worker 104*598139dcSAndroid Build Coastguard Worker PendingReaderThreadKey pending_reader_thread_key_ GUARDED_BY(logd_lock); 105*598139dcSAndroid Build Coastguard Worker // Set to true to indicate the thread has finished. 106*598139dcSAndroid Build Coastguard Worker bool finished_ GUARDED_BY(logd_lock) = false; 107*598139dcSAndroid Build Coastguard Worker // Set to true to indicate the thread is tracked by AppOps. 108*598139dcSAndroid Build Coastguard Worker bool tracked_ GUARDED_BY(logd_lock) = false; 109*598139dcSAndroid Build Coastguard Worker 110*598139dcSAndroid Build Coastguard Worker // Set to true to cause the thread to end and the LogReaderThread to delete itself. 111*598139dcSAndroid Build Coastguard Worker bool release_ GUARDED_BY(logd_lock) = false; 112*598139dcSAndroid Build Coastguard Worker 113*598139dcSAndroid Build Coastguard Worker // If set to non-zero, only pids equal to this are read by the reader. 114*598139dcSAndroid Build Coastguard Worker const pid_t pid_; 115*598139dcSAndroid Build Coastguard Worker // When a reader is referencing (via start_) old elements in the log buffer, and the log 116*598139dcSAndroid Build Coastguard Worker // buffer's size grows past its memory limit, the log buffer may request the reader to skip 117*598139dcSAndroid Build Coastguard Worker // ahead a specified number of logs. 118*598139dcSAndroid Build Coastguard Worker unsigned int skip_ahead_[LOG_ID_MAX] GUARDED_BY(logd_lock); 119*598139dcSAndroid Build Coastguard Worker // LogBuffer::FlushTo() needs to store state across subsequent calls. 120*598139dcSAndroid Build Coastguard Worker std::unique_ptr<FlushToState> flush_to_state_ GUARDED_BY(logd_lock); 121*598139dcSAndroid Build Coastguard Worker 122*598139dcSAndroid Build Coastguard Worker // These next three variables are used for reading only the most recent lines aka `adb logcat 123*598139dcSAndroid Build Coastguard Worker // -t` / `adb logcat -T`. 124*598139dcSAndroid Build Coastguard Worker // tail_ is the number of most recent lines to print. 125*598139dcSAndroid Build Coastguard Worker unsigned long tail_; 126*598139dcSAndroid Build Coastguard Worker // count_ is the result of a first pass through the log buffer to determine how many total 127*598139dcSAndroid Build Coastguard Worker // messages there are. 128*598139dcSAndroid Build Coastguard Worker unsigned long count_; 129*598139dcSAndroid Build Coastguard Worker // index_ is used along with count_ to only start sending lines once index_ > (count_ - tail_) 130*598139dcSAndroid Build Coastguard Worker // and to disconnect the reader (if it is dumpAndClose, `adb logcat -t`), when index_ >= count_. 131*598139dcSAndroid Build Coastguard Worker unsigned long index_; 132*598139dcSAndroid Build Coastguard Worker 133*598139dcSAndroid Build Coastguard Worker // When a reader requests logs starting from a given timestamp, its stored here for the first 134*598139dcSAndroid Build Coastguard Worker // pass, such that logs before this time stamp that are accumulated in the buffer are ignored. 135*598139dcSAndroid Build Coastguard Worker log_time start_time_; 136*598139dcSAndroid Build Coastguard Worker // CLOCK_MONOTONIC based deadline used for log wrapping. If this deadline expires before logs 137*598139dcSAndroid Build Coastguard Worker // wrap, then wake up and send the logs to the reader anyway. 138*598139dcSAndroid Build Coastguard Worker std::chrono::steady_clock::time_point deadline_ GUARDED_BY(logd_lock); 139*598139dcSAndroid Build Coastguard Worker // If this reader is 'dumpAndClose' and will disconnect once it has read its intended logs. 140*598139dcSAndroid Build Coastguard Worker const bool non_block_; 141*598139dcSAndroid Build Coastguard Worker }; 142