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 <sys/types.h> 22 #include <time.h> 23 24 #include <list> 25 26 #include <log/log.h> 27 #include <sysutils/SocketClient.h> 28 29 typedef unsigned int log_mask_t; 30 31 class LogReader; 32 class LogBufferElement; 33 34 class LogTimeEntry { 35 static pthread_mutex_t timesLock; 36 unsigned int mRefCount; 37 bool mRelease; 38 bool mError; 39 bool threadRunning; 40 bool leadingDropped; 41 pthread_cond_t threadTriggeredCondition; 42 pthread_t mThread; 43 LogReader& mReader; 44 static void* threadStart(void* me); 45 static void threadStop(void* me); 46 const log_mask_t mLogMask; 47 const pid_t mPid; 48 unsigned int skipAhead[LOG_ID_MAX]; 49 pid_t mLastTid[LOG_ID_MAX]; 50 unsigned long mCount; 51 unsigned long mTail; 52 unsigned long mIndex; 53 54 public: 55 LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock, 56 unsigned long tail, log_mask_t logMask, pid_t pid, 57 log_time start, uint64_t timeout); 58 59 SocketClient* mClient; 60 log_time mStart; 61 struct timespec mTimeout; 62 const bool mNonBlock; 63 const log_time mEnd; // only relevant if mNonBlock 64 65 // Protect List manipulations 66 static void wrlock(void) { 67 pthread_mutex_lock(×Lock); 68 } 69 static void rdlock(void) { 70 pthread_mutex_lock(×Lock); 71 } 72 static void unlock(void) { 73 pthread_mutex_unlock(×Lock); 74 } 75 76 void startReader_Locked(void); 77 78 bool runningReader_Locked(void) const { 79 return threadRunning || mRelease || mError || mNonBlock; 80 } 81 void triggerReader_Locked(void) { 82 pthread_cond_signal(&threadTriggeredCondition); 83 } 84 85 void triggerSkip_Locked(log_id_t id, unsigned int skip) { 86 skipAhead[id] = skip; 87 } 88 void cleanSkip_Locked(void); 89 90 // These called after LogTimeEntry removed from list, lock implicitly held 91 void release_nodelete_Locked(void) { 92 mRelease = true; 93 pthread_cond_signal(&threadTriggeredCondition); 94 // assumes caller code path will call decRef_Locked() 95 } 96 97 void release_Locked(void) { 98 mRelease = true; 99 pthread_cond_signal(&threadTriggeredCondition); 100 if (mRefCount || threadRunning) { 101 return; 102 } 103 // No one else is holding a reference to this 104 delete this; 105 } 106 107 // Called to mark socket in jeopardy 108 void error_Locked(void) { 109 mError = true; 110 } 111 void error(void) { 112 wrlock(); 113 error_Locked(); 114 unlock(); 115 } 116 117 bool isError_Locked(void) const { 118 return mRelease || mError; 119 } 120 121 // Mark Used 122 // Locking implied, grabbed when protection around loop iteration 123 void incRef_Locked(void) { 124 ++mRefCount; 125 } 126 127 bool owned_Locked(void) const { 128 return mRefCount != 0; 129 } 130 131 void decRef_Locked(void) { 132 if ((mRefCount && --mRefCount) || !mRelease || threadRunning) { 133 return; 134 } 135 // No one else is holding a reference to this 136 delete this; 137 } 138 bool isWatching(log_id_t id) const { 139 return mLogMask & (1 << id); 140 } 141 bool isWatchingMultiple(log_mask_t logMask) const { 142 return mLogMask & logMask; 143 } 144 // flushTo filter callbacks 145 static int FilterFirstPass(const LogBufferElement* element, void* me); 146 static int FilterSecondPass(const LogBufferElement* element, void* me); 147 }; 148 149 typedef std::list<LogTimeEntry*> LastLogTimes; 150 151 #endif // _LOGD_LOG_TIMES_H__ 152