text: // Copyright 2017 The Fuchsia Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef ZIRCON_SYSTEM_ULIB_TRACE_PROVIDER_PROVIDER_IMPL_H_
  #define ZIRCON_SYSTEM_ULIB_TRACE_PROVIDER_PROVIDER_IMPL_H_
  
  #include <lib/async/cpp/wait.h>
  #include <lib/trace-engine/handler.h>
  #include <lib/trace-engine/types.h>
  #include <lib/trace-provider/provider.h>
  #include <lib/zx/channel.h>
  #include <lib/zx/fifo.h>
  #include <lib/zx/time.h>
  #include <lib/zx/vmo.h>
  
  #include <string>
  #include <vector>
  
  // Provide a definition for the opaque type declared in provider.h.
  struct trace_provider {};
  
  namespace trace {
  namespace internal {
  
  class TraceProviderImpl final : public trace_provider_t {
   public:
    TraceProviderImpl(async_dispatcher_t* dispatcher, zx::channel channel);
    ~TraceProviderImpl();
  
    async_dispatcher_t* dispatcher() const { return dispatcher_; }
  
   private:
    class Connection final {
     public:
      Connection(TraceProviderImpl* impl, zx::channel channel);
      ~Connection();
  
     private:
      void Handle(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                  const zx_packet_signal_t* signal);
  
      bool ReadMessage();
      bool DecodeAndDispatch(uint8_t* buffer, uint32_t num_bytes, zx_handle_info_t* handles,
                             uint32_t num_handles);
      void Close();
  
      TraceProviderImpl* const impl_;
      zx::channel channel_;
      async::WaitMethod<Connection, &Connection::Handle> wait_;
    };
  
    void Initialize(trace_buffering_mode_t buffering_mode, zx::vmo buffer, zx::fifo fifo,
                    std::vector<std::string> categories);
    void Start(trace_start_mode_t start_mode, std::vector<std::string> additional_categories);
  
    void Stop();
    void Terminate();
  
    void OnStopped();
    void OnTerminated();
    void OnClose();
  
    async_dispatcher_t* const dispatcher_;
    Connection connection_;
  
    TraceProviderImpl(const TraceProviderImpl&) = delete;
    TraceProviderImpl(TraceProviderImpl&&) = delete;
    TraceProviderImpl& operator=(const TraceProviderImpl&) = delete;
    TraceProviderImpl& operator=(TraceProviderImpl&&) = delete;
  };
  
  }  // namespace internal
  }  // namespace trace
  
  #endif  // ZIRCON_SYSTEM_ULIB_TRACE_PROVIDER_PROVIDER_IMPL_H_
  