logd: add locks around ~SerializedFlushToState

This accesses shared resources in SerializedLogBuffer and therefore
requires a lock.

Bug: 169736426
Test: malloc_debug_system_tests
Change-Id: I807c65f4719481f933b4917a50f83f933b1929fb
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index a98c4b9..0259266 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -19,6 +19,7 @@
 #include <sys/types.h>
 
 #include <functional>
+#include <memory>
 
 #include <log/log.h>
 #include <log/log_read.h>
@@ -62,6 +63,7 @@
                     const char* msg, uint16_t len) = 0;
 
     virtual std::unique_ptr<FlushToState> CreateFlushToState(uint64_t start, LogMask log_mask) = 0;
+    virtual void DeleteFlushToState(std::unique_ptr<FlushToState>) {}
     virtual bool FlushTo(
             LogWriter* writer, FlushToState& state,
             const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
diff --git a/logd/LogReaderThread.cpp b/logd/LogReaderThread.cpp
index 4a8be01..6ac9741 100644
--- a/logd/LogReaderThread.cpp
+++ b/logd/LogReaderThread.cpp
@@ -72,6 +72,7 @@
                     [this](log_id_t log_id, pid_t pid, uint64_t sequence, log_time realtime) {
                         return FilterFirstPass(log_id, pid, sequence, realtime);
                     });
+            log_buffer_->DeleteFlushToState(std::move(first_pass_state));
         }
         bool flush_success = log_buffer_->FlushTo(
                 writer_.get(), *flush_to_state_,
@@ -105,6 +106,10 @@
         }
     }
 
+    lock.unlock();
+    log_buffer_->DeleteFlushToState(std::move(flush_to_state_));
+    lock.lock();
+
     writer_->Release();
 
     auto& log_reader_threads = reader_list_->reader_threads();
diff --git a/logd/LogReaderThread.h b/logd/LogReaderThread.h
index 20624f2..f1b673f 100644
--- a/logd/LogReaderThread.h
+++ b/logd/LogReaderThread.h
@@ -53,7 +53,7 @@
 
     bool IsWatching(log_id_t id) const { return flush_to_state_->log_mask() & (1 << id); }
     bool IsWatchingMultiple(LogMask log_mask) const {
-        return flush_to_state_->log_mask() & log_mask;
+        return flush_to_state_ && flush_to_state_->log_mask() & log_mask;
     }
 
     std::string name() const { return writer_->name(); }
diff --git a/logd/SerializedLogBuffer.cpp b/logd/SerializedLogBuffer.cpp
index fa90878..6d1576f 100644
--- a/logd/SerializedLogBuffer.cpp
+++ b/logd/SerializedLogBuffer.cpp
@@ -201,6 +201,11 @@
     return std::make_unique<SerializedFlushToState>(start, log_mask);
 }
 
+void SerializedLogBuffer::DeleteFlushToState(std::unique_ptr<FlushToState> state) {
+    auto lock = std::unique_lock{lock_};
+    state.reset();
+}
+
 bool SerializedLogBuffer::FlushTo(
         LogWriter* writer, FlushToState& abstract_state,
         const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
diff --git a/logd/SerializedLogBuffer.h b/logd/SerializedLogBuffer.h
index 294cfe6..9164526 100644
--- a/logd/SerializedLogBuffer.h
+++ b/logd/SerializedLogBuffer.h
@@ -42,6 +42,7 @@
     int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg,
             uint16_t len) override;
     std::unique_ptr<FlushToState> CreateFlushToState(uint64_t start, LogMask log_mask) override;
+    void DeleteFlushToState(std::unique_ptr<FlushToState> state) override;
     bool FlushTo(LogWriter* writer, FlushToState& state,
                  const std::function<FilterResult(log_id_t log_id, pid_t pid, uint64_t sequence,
                                                   log_time realtime)>& filter) override;