// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/debug/wasm/gdb-server/gdb-server-thread.h"
#include "src/debug/wasm/gdb-server/gdb-server.h"
#include "src/debug/wasm/gdb-server/session.h"

namespace v8 {
namespace internal {
namespace wasm {
namespace gdb_server {

GdbServerThread::GdbServerThread(GdbServer* gdb_server)
    : Thread(v8::base::Thread::Options("GdbServerThread")),
      gdb_server_(gdb_server),
      start_semaphore_(0) {}

bool GdbServerThread::StartAndInitialize() {
  // Executed in the Isolate thread.
  if (!Start()) {
    return false;
  }

  // We need to make sure that {Stop} is never called before the thread has
  // completely initialized {transport_} and {target_}. Otherwise there could be
  // a race condition where in the main thread {Stop} might get called before
  // the transport is created, and then in the GDBServer thread we may have time
  // to setup the transport and block on accept() before the main thread blocks
  // on joining the thread.
  // The small performance hit caused by this Wait should be negligeable because
  // this operation happensat most once per process and only when the
  // --wasm-gdb-remote flag is set.
  start_semaphore_.Wait();
  return !!target_;
}

void GdbServerThread::CleanupThread() {
  // Executed in the GdbServer thread.
  v8::base::MutexGuard guard(&mutex_);

  target_ = nullptr;
  transport_ = nullptr;

#if _WIN32
  ::WSACleanup();
#endif
}

void GdbServerThread::Run() {
  // Executed in the GdbServer thread.
#ifdef _WIN32
  // Initialize Winsock
  WSADATA wsaData;
  int iResult = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
  if (iResult != 0) {
    TRACE_GDB_REMOTE("GdbServerThread::Run: WSAStartup failed\n");
    return;
  }
#endif

  // If the default port is not available, try any port.
  SocketBinding socket_binding = SocketBinding::Bind(FLAG_wasm_gdb_remote_port);
  if (!socket_binding.IsValid()) {
    socket_binding = SocketBinding::Bind(0);
  }
  if (!socket_binding.IsValid()) {
    TRACE_GDB_REMOTE("GdbServerThread::Run: Failed to bind any TCP port\n");
    return;
  }
  TRACE_GDB_REMOTE("gdb-remote(%d) : Connect GDB with 'target remote :%d\n",
                   __LINE__, socket_binding.GetBoundPort());

  transport_ = socket_binding.CreateTransport();
  target_ = std::make_unique<Target>(gdb_server_);

  // Here we have completed the initialization, and the thread that called
  // {StartAndInitialize} may resume execution.
  start_semaphore_.Signal();

  while (!target_->IsTerminated()) {
    // Wait for incoming connections.
    if (!transport_->AcceptConnection()) {
      continue;
    }

    // Create a new session for this connection
    Session session(transport_.get());
    TRACE_GDB_REMOTE("GdbServerThread: Connected\n");

    // Run this session for as long as it lasts
    target_->Run(&session);
  }
  CleanupThread();
}

void GdbServerThread::Stop() {
  // Executed in the Isolate thread.

  // Synchronized, becauses {Stop} might be called while {Run} is still
  // initializing {transport_} and {target_}. If this happens and the thread is
  // blocked waiting for an incoming connection or GdbServer for incoming
  // packets, it will unblocked when {transport_} is closed.
  v8::base::MutexGuard guard(&mutex_);

  if (target_) {
    target_->Terminate();
  }

  if (transport_) {
    transport_->Close();
  }
}

}  // namespace gdb_server
}  // namespace wasm
}  // namespace internal
}  // namespace v8
