/* Run a function on the main thread
   Copyright (C) 2019-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "run-on-main-thread.h"
#include "ser-event.h"
#include "gdbsupport/cleanups.h"
#include "gdbsupport/cxx-thread.h"
#include "gdbsupport/event-loop.h"

/* The serial event used when posting runnables.  */

static struct serial_event *runnable_event;

/* Runnables that have been posted.  */

static std::vector<std::function<void ()>> runnables;

/* Mutex to hold when handling RUNNABLE_EVENT or RUNNABLES.  */

static gdb::mutex runnable_mutex;

/* The main thread's thread id.  */

static gdb::thread::id main_thread_id;

/* Run all the queued runnables.  */

static void
run_events (int error, gdb_client_data client_data)
{
  std::vector<std::function<void ()>> local;

  /* Hold the lock while changing the globals, but not while running
     the runnables.  */
  {
    gdb::lock_guard<gdb::mutex> lock (runnable_mutex);

    /* Clear the event fd.  Do this before flushing the events list,
       so that any new event post afterwards is sure to re-awaken the
       event loop.  */
    serial_event_clear (runnable_event);

    /* Move the vector in case running a runnable pushes a new
       runnable.  */
    local = std::move (runnables);
  }

  for (auto &item : local)
    {
      try
	{
	  item ();
	}
      catch (const gdb_exception_forced_quit &e)
	{
	  /* GDB is terminating, so:
	     - make sure this is propagated, and
	     - no need to keep running things, so propagate immediately.  */
	  throw;
	}
      catch (const gdb_exception_quit &e)
	{
	  /* Should cancellation of a runnable event cancel the execution of
	     the following one?  The answer is not clear, so keep doing what
	     we've done so far: ignore this exception.  */
	}
      catch (const gdb_exception &)
	{
	  /* Ignore exceptions in the callback.  */
	}
    }
}

/* See run-on-main-thread.h.  */

void
run_on_main_thread (std::function<void ()> &&func)
{
  gdb::lock_guard<gdb::mutex> lock (runnable_mutex);
  runnables.emplace_back (std::move (func));
  serial_event_set (runnable_event);
}

static bool main_thread_id_initialized = false;

/* See run-on-main-thread.h.  */

bool
is_main_thread ()
{
  /* Initialize main_thread_id on first use of is_main_thread.  */
  if (!main_thread_id_initialized)
    {
      main_thread_id_initialized = true;

      main_thread_id = gdb::this_thread::get_id ();
    }

  return gdb::this_thread::get_id () == main_thread_id;
}

INIT_GDB_FILE (run_on_main_thread)
{
  /* The variable main_thread_id should be initialized when entering main, or
     at an earlier use, so it should already be initialized here.  */
  gdb_assert (main_thread_id_initialized);

  /* Assume that we execute this in the main thread.  */
  gdb_assert (is_main_thread ());

  runnable_event = make_serial_event ();
  add_file_handler (serial_event_fd (runnable_event), run_events, nullptr,
		    "run-on-main-thread");

  /* A runnable may refer to an extension language.  So, we want to
     make sure any pending ones have been deleted before the extension
     languages are shut down.  */
  add_final_cleanup ([] ()
    {
      gdb::lock_guard<gdb::mutex> lock (runnable_mutex);
      runnables.clear ();
    });
}
