Actually manage memory in the old-style AOS logging

LeakSanitizer should be happy with it now. It's also still just as
thread-safe.

Change-Id: Id09a0349657cf4f719267b053f0ea3d8ec366256
diff --git a/aos/logging/implementations.h b/aos/logging/implementations.h
index 0e17165..e8a2213 100644
--- a/aos/logging/implementations.h
+++ b/aos/logging/implementations.h
@@ -11,6 +11,7 @@
 
 #include <atomic>
 #include <functional>
+#include <memory>
 #include <string>
 
 #include "aos/logging/context.h"
@@ -118,31 +119,31 @@
   FILE *const stream_;
 };
 
-// Adds another implementation to the stack of implementations in this
-// task/thread.
-// Any tasks/threads created after this call will also use this implementation.
-// The cutoff is when the state in a given task/thread is created (either lazily
-// when needed or by calling Load()).
-// The logging system takes ownership of implementation. It will delete it if
-// necessary, so it must be created with new.
-// TODO: Log implementations are never deleted. Need means to safely deregister.
-void SetImplementation(LogImplementation *implementation,
-                       bool update_global = true);
+std::shared_ptr<LogImplementation> GetImplementation();
 
-// Updates the log implementation for the current thread, returning the current
-// implementation.
-LogImplementation *SwapImplementation(LogImplementation *implementation);
+// Sets the current implementation.
+void SetImplementation(std::shared_ptr<LogImplementation> implementation);
 
-LogImplementation *GetImplementation();
+// Updates the log implementation, returning the current implementation.
+std::shared_ptr<LogImplementation> SwapImplementation(
+    std::shared_ptr<LogImplementation> implementation);
 
 // Must be called at least once per process/load before anything else is
 // called. This function is safe to call multiple times from multiple
 // tasks/threads.
 void Init();
 
-// Forces all of the state that is usually lazily created when first needed to
-// be created when called. Cleanup() will delete it.
-void Load();
+class CallbackLogImplementation : public HandleMessageLogImplementation {
+ public:
+  CallbackLogImplementation(
+      const ::std::function<void(const LogMessage &)> &callback)
+      : callback_(callback) {}
+
+ private:
+  void HandleMessage(const LogMessage &message) override { callback_(message); }
+
+  ::std::function<void(const LogMessage &)> callback_;
+};
 
 // Resets all information in this task/thread to its initial state.
 // NOTE: This is not the opposite of Init(). The state that this deletes is
@@ -150,17 +151,25 @@
 void Cleanup();
 
 void RegisterCallbackImplementation(
-    const ::std::function<void(const LogMessage &)> &callback,
-    bool update_global = true);
+    const ::std::function<void(const LogMessage &)> &callback);
 
 class ScopedLogRestorer {
  public:
-  ScopedLogRestorer() { prev_impl_ = GetImplementation(); }
+  ScopedLogRestorer() = default;
 
-  ~ScopedLogRestorer() { SetImplementation(prev_impl_); }
+  ~ScopedLogRestorer() {
+    if (prev_impl_) {
+      SetImplementation(std::move(prev_impl_));
+    }
+    Cleanup();
+  }
+
+  void Swap(std::shared_ptr<LogImplementation> new_impl) {
+    prev_impl_ = SwapImplementation(std::move(new_impl));
+  }
 
  private:
-  LogImplementation *prev_impl_;
+  std::shared_ptr<LogImplementation> prev_impl_;
 };
 
 // This is where all of the code that is only used by actual LogImplementations