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