Home | History | Annotate | Download | only in logd
      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(&timesLock);
     68     }
     69     static void rdlock(void) {
     70         pthread_mutex_lock(&timesLock);
     71     }
     72     static void unlock(void) {
     73         pthread_mutex_unlock(&timesLock);
     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