void *LogTimeEntry::threadStart(void *obj) { prctl(PR_SET_NAME, "logd.reader.per"); LogTimeEntry *me = reinterpret_cast<LogTimeEntry *>(obj); pthread_cleanup_push(threadStop, obj); SocketClient *client = me->mClient; if (!client) { me->error(); return NULL; } LogBuffer &logbuf = me->mReader.logbuf(); bool privileged = FlushCommand::hasReadLogs(client); lock(); while (me->threadRunning && !me->isError_Locked()) { uint64_t start = me->mStart; unlock(); if (me->mTail) { logbuf.flushTo(client, start, privileged, FilterFirstPass, me); } start = logbuf.flushTo(client, start, privileged, FilterSecondPass, me); lock(); if (start == LogBufferElement::FLUSH_ERROR) { me->error_Locked(); } if (me->mNonBlock || !me->threadRunning || me->isError_Locked()) { break; } me->cleanSkip_Locked(); pthread_cond_wait(&me->threadTriggeredCondition, ×Lock); } unlock(); pthread_cleanup_pop(true); return NULL; }
void LogTimeEntry::threadStop(void *obj) { LogTimeEntry *me = reinterpret_cast<LogTimeEntry *>(obj); lock(); if (me->mNonBlock) { me->error_Locked(); } SocketClient *client = me->mClient; if (me->isError_Locked()) { LogReader &reader = me->mReader; LastLogTimes × = reader.logbuf().mTimes; LastLogTimes::iterator it = times.begin(); while(it != times.end()) { if (*it == me) { times.erase(it); me->release_Locked(); break; } it++; } me->mClient = NULL; reader.release(client); } if (client) { client->decRef(); } me->threadRunning = false; me->decRef_Locked(); unlock(); }