logd: persistent reader threads

Bug: 16822776
Change-Id: I5bea468a41089b51108880044f32e2b2df1278e7
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index e7e3ec2..c6dc174 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -33,7 +33,6 @@
         , mRelease(false)
         , mError(false)
         , threadRunning(false)
-        , threadTriggered(true)
         , mReader(reader)
         , mLogMask(logMask)
         , mPid(pid)
@@ -45,7 +44,9 @@
         , mStart(start)
         , mNonBlock(nonBlock)
         , mEnd(CLOCK_MONOTONIC)
-{ }
+{
+        pthread_cond_init(&threadTriggeredCondition, NULL);
+}
 
 void LogTimeEntry::startReader_Locked(void) {
     pthread_attr_t attr;
@@ -74,7 +75,6 @@
 
     lock();
 
-    me->threadRunning = false;
     if (me->mNonBlock) {
         me->error_Locked();
     }
@@ -103,6 +103,7 @@
         client->decRef();
     }
 
+    me->threadRunning = false;
     me->decRef_Locked();
 
     unlock();
@@ -119,6 +120,7 @@
     if (!client) {
         me->error();
         pthread_exit(NULL);
+        // NOTREACH
     }
 
     LogBuffer &logbuf = me->mReader.logbuf();
@@ -127,12 +129,7 @@
 
     lock();
 
-    me->threadTriggered = true;
-
-    while(me->threadTriggered && !me->isError_Locked()) {
-
-        me->threadTriggered = false;
-
+    while (me->threadRunning && !me->isError_Locked()) {
         log_time start = me->mStart;
 
         unlock();
@@ -142,24 +139,24 @@
         }
         start = logbuf.flushTo(client, start, privileged, FilterSecondPass, me);
 
+        lock();
+
         if (start == LogBufferElement::FLUSH_ERROR) {
-            me->error();
+            me->error_Locked();
         }
 
-        if (me->mNonBlock) {
-            lock();
+        if (me->mNonBlock || !me->threadRunning || me->isError_Locked()) {
             break;
         }
 
-        sched_yield();
-
-        lock();
+        pthread_cond_wait(&me->threadTriggeredCondition, &timesLock);
     }
 
     unlock();
 
     pthread_exit(NULL);
 
+    // NOTREACH
     pthread_cleanup_pop(true);
 
     return NULL;
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index beaf646..0bfa7a2 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -31,7 +31,7 @@
     bool mRelease;
     bool mError;
     bool threadRunning;
-    bool threadTriggered;
+    pthread_cond_t threadTriggeredCondition;
     pthread_t mThread;
     LogReader &mReader;
     static void *threadStart(void *me);
@@ -63,12 +63,16 @@
     bool runningReader_Locked(void) const {
         return threadRunning || mRelease || mError || mNonBlock;
     }
-    void triggerReader_Locked(void) { threadTriggered = true; }
+    void triggerReader_Locked(void) {
+        pthread_cond_signal(&threadTriggeredCondition);
+    }
+
     void triggerSkip_Locked(unsigned int skip) { skipAhead = skip; }
 
     // Called after LogTimeEntry removed from list, lock implicitly held
     void release_Locked(void) {
         mRelease = true;
+        pthread_cond_signal(&threadTriggeredCondition);
         if (mRefCount || threadRunning) {
             return;
         }
@@ -78,7 +82,7 @@
 
     // Called to mark socket in jeopardy
     void error_Locked(void) { mError = true; }
-    void error(void) { lock(); mError = true; unlock(); }
+    void error(void) { lock(); error_Locked(); unlock(); }
 
     bool isError_Locked(void) const { return mRelease || mError; }