Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a86a9708 authored by Mike Yu's avatar Mike Yu
Browse files

Add LockedRingBuffer

This is a refactor for DnsQueryLog. No functional behavior change.

Bug: 79727473
Test: resolv_unit_test passed
Test: adb shell dumpsys dnsresolver querylog
Change-Id: Id9fc9b7868dab5861feda5ab2cb04759e7a34846
parent 7b2978e7
Loading
Loading
Loading
Loading
+2 −7
Original line number Diff line number Diff line
@@ -59,11 +59,7 @@ std::string timestampToString(const std::chrono::system_clock::time_point& ts) {
}  // namespace

void DnsQueryLog::push(Record&& record) {
    std::lock_guard guard(mLock);
    mQueue.push_back(std::move(record));
    if (mQueue.size() > mCapacity) {
        mQueue.pop_front();
    }
    mQueue.push(std::move(record));
}

void DnsQueryLog::dump(netdutils::DumpWriter& dw) const {
@@ -71,8 +67,7 @@ void DnsQueryLog::dump(netdutils::DumpWriter& dw) const {
    netdutils::ScopedIndent indentStats(dw);
    const auto now = std::chrono::system_clock::now();

    std::lock_guard guard(mLock);
    for (const auto& record : mQueue) {
    for (const auto& record : mQueue.copy()) {
        if (now - record.timestamp > mValidityTimeMs) continue;

        const std::string maskedHostname = maskHostname(record.hostname);
+7 −9
Original line number Diff line number Diff line
@@ -17,16 +17,16 @@

#pragma once

#include <deque>
#include <string>
#include <vector>

#include <android-base/thread_annotations.h>
#include <netdutils/DumpWriter.h>

#include "LockedQueue.h"

namespace android::net {

// A circular buffer based class used for query logging. It's thread-safe for concurrent access.
// This class stores query records in a locked ring buffer. It's thread-safe for concurrent access.
class DnsQueryLog {
  public:
    static constexpr std::string_view DUMP_KEYWORD = "querylog";
@@ -52,15 +52,13 @@ class DnsQueryLog {
    // Allow the tests to set the capacity and the validaty time in milliseconds.
    DnsQueryLog(size_t size = kDefaultLogSize,
                std::chrono::milliseconds time = kDefaultValidityMinutes)
        : mCapacity(size), mValidityTimeMs(time) {}
        : mQueue(size), mValidityTimeMs(time) {}

    void push(Record&& record) EXCLUDES(mLock);
    void dump(netdutils::DumpWriter& dw) const EXCLUDES(mLock);
    void push(Record&& record);
    void dump(netdutils::DumpWriter& dw) const;

  private:
    mutable std::mutex mLock;
    std::deque<Record> mQueue GUARDED_BY(mLock);
    const size_t mCapacity;
    LockedRingBuffer<Record> mQueue;
    const std::chrono::milliseconds mValidityTimeMs;

    // The capacity of the circular buffer.
+24 −0
Original line number Diff line number Diff line
@@ -46,6 +46,30 @@ class LockedQueue {
    std::deque<T> mQueue GUARDED_BY(mLock);
};

template <typename T>
class LockedRingBuffer {
  public:
    explicit LockedRingBuffer(size_t size) : mCapacity(size) {}

    void push(T&& record) {
        std::lock_guard guard(mLock);
        mQueue.push_back(std::move(record));
        if (mQueue.size() > mCapacity) {
            mQueue.pop_front();
        }
    }

    std::deque<T> copy() const {
        std::lock_guard guard(mLock);
        return mQueue;
    }

  private:
    mutable std::mutex mLock;
    const size_t mCapacity;
    std::deque<T> mQueue GUARDED_BY(mLock);
};

}  // end of namespace net
}  // end of namespace android