log_time LogBuffer::flushTo( SocketClient *reader, const log_time start, bool privileged, bool (*filter)(const LogBufferElement *element, void *arg), void *arg) { LogBufferElementCollection::iterator it; log_time max = start; uid_t uid = reader->getUid(); pthread_mutex_lock(&mLogElementsLock); for (it = mLogElements.begin(); it != mLogElements.end(); ++it) { LogBufferElement *element = *it; if (!privileged && (element->getUid() != uid)) { continue; } if (element->getMonotonicTime() <= start) { continue; } // NB: calling out to another object with mLogElementsLock held (safe) if (filter && !(*filter)(element, arg)) { continue; } pthread_mutex_unlock(&mLogElementsLock); // range locking in LastLogTimes looks after us max = element->flushTo(reader); if (max == element->FLUSH_ERROR) { return max; } pthread_mutex_lock(&mLogElementsLock); } pthread_mutex_unlock(&mLogElementsLock); return max; }
uint64_t LogBuffer::flushTo( SocketClient *reader, const uint64_t start, bool privileged, int (*filter)(const LogBufferElement *element, void *arg), void *arg) { LogBufferElementCollection::iterator it; uint64_t max = start; uid_t uid = reader->getUid(); pthread_mutex_lock(&mLogElementsLock); if (start <= 1) { // client wants to start from the beginning it = mLogElements.begin(); } else { // Client wants to start from some specified time. Chances are // we are better off starting from the end of the time sorted list. for (it = mLogElements.end(); it != mLogElements.begin(); /* do nothing */) { --it; LogBufferElement *element = *it; if (element->getSequence() <= start) { it++; break; } } } for (; it != mLogElements.end(); ++it) { LogBufferElement *element = *it; if (!privileged && (element->getUid() != uid)) { continue; } if (element->getSequence() <= start) { continue; } // NB: calling out to another object with mLogElementsLock held (safe) if (filter) { int ret = (*filter)(element, arg); if (ret == false) { continue; } if (ret != true) { break; } } pthread_mutex_unlock(&mLogElementsLock); // range locking in LastLogTimes looks after us max = element->flushTo(reader, this); if (max == element->FLUSH_ERROR) { return max; } pthread_mutex_lock(&mLogElementsLock); } pthread_mutex_unlock(&mLogElementsLock); return max; }