text: // Copyright 2018 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.
  
  #pragma once
  
  #include <fbl/function.h>
  #include <fbl/intrusive_single_list.h>
  #include <fbl/string.h>
  #include <fbl/unique_ptr.h>
  #include <fbl/vector.h>
  #include <launchpad/launchpad.h>
  #include <lib/async/cpp/wait.h>
  #include <lib/fidl/cpp/message_buffer.h>
  #include <lib/zx/channel.h>
  #include <stdint.h>
  
  #include <utility>
  
  namespace launcher {
  
  class LauncherImpl : public fbl::SinglyLinkedListable<fbl::unique_ptr<LauncherImpl>> {
  public:
      using ErrorCallback = fbl::Function<void(zx_status_t)>;
  
      explicit LauncherImpl(zx::channel channel);
      ~LauncherImpl();
  
      zx_status_t Begin(async_dispatcher_t* dispatcher);
  
      void set_error_handler(ErrorCallback error_handler) {
          error_handler_ = std::move(error_handler);
      }
  
      LauncherImpl* GetKey() const { return const_cast<LauncherImpl*>(this); }
      static size_t GetHash(const LauncherImpl* impl) { return reinterpret_cast<uintptr_t>(impl); }
  
  private:
      void OnHandleReady(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                         const zx_packet_signal_t* signal);
      zx_status_t ReadAndDispatchMessage(fidl::MessageBuffer* buffer);
  
      zx_status_t Launch(fidl::MessageBuffer* buffer, fidl::Message message);
      zx_status_t CreateWithoutStarting(fidl::MessageBuffer* buffer, fidl::Message message);
      zx_status_t AddArgs(fidl::Message message);
      zx_status_t AddEnvirons(fidl::Message message);
      zx_status_t AddNames(fidl::Message message);
      zx_status_t AddHandles(fidl::Message message);
  
      void PrepareLaunchpad(const fidl::Message& message, launchpad_t** lp);
      void NotifyError(zx_status_t error);
      void Reset();
  
      zx::channel channel_;
      async::WaitMethod<LauncherImpl, &LauncherImpl::OnHandleReady> wait_;
      ErrorCallback error_handler_;
  
      // Per-launch state.
      fbl::Vector<fbl::String> args_;
      fbl::Vector<fbl::String> environs_;
      fbl::Vector<fbl::String> nametable_;
      fbl::Vector<uint32_t> ids_;
      fbl::Vector<zx::handle> handles_;
      zx::handle ldsvc_;
  };
  
  } // namespace launcher
  