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 #ifndef _LOGD_LOG_TIMES_H__ 18 #define _LOGD_LOG_TIMES_H__ 19 20 #include <pthread.h> 21 #include <time.h> 22 #include <sys/types.h> 23 24 #include <list> 25 26 #include <sysutils/SocketClient.h> 27 #include <log/log.h> 28 29 class LogReader; 30 31 class LogTimeEntry { 32 static pthread_mutex_t timesLock; 33 unsigned int mRefCount; 34 bool mRelease; 35 bool mError; 36 bool threadRunning; 37 bool leadingDropped; 38 pthread_cond_t threadTriggeredCondition; 39 pthread_t mThread; 40 LogReader &mReader; 41 static void *threadStart(void *me); 42 static void threadStop(void *me); 43 const unsigned int mLogMask; 44 const pid_t mPid; 45 unsigned int skipAhead[LOG_ID_MAX]; 46 unsigned long mCount; 47 unsigned long mTail; 48 unsigned long mIndex; 49 50 public: 51 LogTimeEntry(LogReader &reader, SocketClient *client, bool nonBlock, 52 unsigned long tail, unsigned int logMask, pid_t pid, 53 uint64_t start); 54 55 SocketClient *mClient; 56 uint64_t mStart; 57 const bool mNonBlock; 58 const uint64_t mEnd; // only relevant if mNonBlock 59 60 // Protect List manipulations lock(void)61 static void lock(void) { pthread_mutex_lock(×Lock); } unlock(void)62 static void unlock(void) { pthread_mutex_unlock(×Lock); } 63 64 void startReader_Locked(void); 65 runningReader_Locked(void)66 bool runningReader_Locked(void) const { 67 return threadRunning || mRelease || mError || mNonBlock; 68 } triggerReader_Locked(void)69 void triggerReader_Locked(void) { 70 pthread_cond_signal(&threadTriggeredCondition); 71 } 72 triggerSkip_Locked(log_id_t id,unsigned int skip)73 void triggerSkip_Locked(log_id_t id, unsigned int skip) { skipAhead[id] = skip; } 74 void cleanSkip_Locked(void); 75 76 // Called after LogTimeEntry removed from list, lock implicitly held release_Locked(void)77 void release_Locked(void) { 78 mRelease = true; 79 pthread_cond_signal(&threadTriggeredCondition); 80 if (mRefCount || threadRunning) { 81 return; 82 } 83 // No one else is holding a reference to this 84 delete this; 85 } 86 87 // Called to mark socket in jeopardy error_Locked(void)88 void error_Locked(void) { mError = true; } error(void)89 void error(void) { lock(); error_Locked(); unlock(); } 90 isError_Locked(void)91 bool isError_Locked(void) const { return mRelease || mError; } 92 93 // Mark Used 94 // Locking implied, grabbed when protection around loop iteration incRef_Locked(void)95 void incRef_Locked(void) { ++mRefCount; } 96 owned_Locked(void)97 bool owned_Locked(void) const { return mRefCount != 0; } 98 decRef_Locked(void)99 void decRef_Locked(void) { 100 if ((mRefCount && --mRefCount) || !mRelease || threadRunning) { 101 return; 102 } 103 // No one else is holding a reference to this 104 delete this; 105 } isWatching(log_id_t id)106 bool isWatching(log_id_t id) { return (mLogMask & (1<<id)) != 0; } 107 // flushTo filter callbacks 108 static int FilterFirstPass(const LogBufferElement *element, void *me); 109 static int FilterSecondPass(const LogBufferElement *element, void *me); 110 }; 111 112 typedef std::list<LogTimeEntry *> LastLogTimes; 113 114 #endif // _LOGD_LOG_TIMES_H__ 115