heapprofd client: add factory method, remove inited_ bit

Side-note: we should consider whether it's worth reordering the Client fields
for better packing/fastpath locality.

Bug: b/120468745
Change-Id: Icb1b1ecdb0ac63e221898c0b29180037bb2421d6
diff --git a/src/profiling/memory/client.h b/src/profiling/memory/client.h
index baef4ca..9de433c 100644
--- a/src/profiling/memory/client.h
+++ b/src/profiling/memory/client.h
@@ -45,13 +45,22 @@
 // the caller needs to synchronize calls behind a mutex or similar.
 class Client {
  public:
-  Client(base::Optional<base::UnixSocketRaw> sock);
-  Client(const std::string& sock_name);
+  // Returns a client that is ready for sampling allocations, using the given
+  // socket (which should already be connected to heapprofd).
+  //
+  // Returns a shared_ptr since that is how the client will ultimately be used,
+  // and to take advantage of std::make_shared putting the object & the control
+  // block in one block of memory.
+  static std::shared_ptr<Client> CreateAndHandshake(base::UnixSocketRaw sock);
+  static base::Optional<base::UnixSocketRaw> ConnectToHeapprofd(
+      const std::string& sock_name);
+
   bool RecordMalloc(uint64_t alloc_size,
                     uint64_t total_size,
                     uint64_t alloc_address);
+
+  // Add address to buffer of deallocations. Flushes the buffer if necessary.
   bool RecordFree(uint64_t alloc_address);
-  void Shutdown();
 
   // Returns the number of bytes to assign to an allocation with the given
   // |alloc_size|, based on the current sampling rate. A return value of zero
@@ -60,29 +69,24 @@
   //
   // Not thread-safe.
   size_t GetSampleSizeLocked(size_t alloc_size) {
-    if (!inited_.load(std::memory_order_acquire))
-      return 0;
     return sampler_.SampleSize(alloc_size);
   }
 
+  // Public for std::make_shared. Use CreateAndHandshake() to create instances
+  // instead.
+  Client(base::UnixSocketRaw sock,
+         ClientConfiguration client_config,
+         SharedRingBuffer shmem,
+         Sampler sampler,
+         const char* main_thread_stack_base);
+
   ClientConfiguration client_config_for_testing() { return client_config_; }
-  bool inited() { return inited_; }
 
  private:
   const char* GetStackBase();
-
-  // Add address to buffer of deallocations. Flush if necessary.
-  // Can be called from any thread. Must not hold free_batch_lock_.
-  bool AddFreeToBatch(uint64_t addr, uint64_t sequence_number);
   // Flush the contents of free_batch_. Must hold free_batch_lock_.
   bool FlushFreesLocked();
 
-  // TODO(rsavitski): used to check if the client is completely initialized
-  // after construction. The reads in RecordFree & GetSampleSizeLocked are no
-  // longer necessary (was an optimization to not do redundant work after
-  // shutdown). Turn into a normal bool, or indicate construction failures
-  // differently.
-  std::atomic<bool> inited_{false};
   ClientConfiguration client_config_;
   // sampler_ operations are not thread-safe.
   Sampler sampler_;
@@ -92,7 +96,7 @@
   FreeBatch free_batch_;
   std::timed_mutex free_batch_lock_;
 
-  const char* main_thread_stack_base_ = nullptr;
+  const char* main_thread_stack_base_{nullptr};
   std::atomic<uint64_t> sequence_number_{0};
   SharedRingBuffer shmem_;
 };