/* Serial interface for a selectable event.
   Copyright (C) 2016-2019 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 "defs.h"
#include "ser-event.h"
#include "serial.h"
#include "gdbsupport/filestuff.h"
#if CXX_STD_THREAD
#include <mutex>
#endif
#include "event-loop.h"

/* On POSIX hosts, a serial_event is basically an abstraction for the
   classical self-pipe trick.

   On Windows, a serial_event is a wrapper around a native Windows
   event object.  Because we want to interface with gdb_select, which
   takes file descriptors, we need to wrap that Windows event object
   in a file descriptor.  As _open_osfhandle can not be used with
   event objects, we instead create a dummy file wrap that in a file
   descriptor with _open_osfhandle, and pass that as selectable
   descriptor to callers.  As Windows' gdb_select converts file
   descriptors back to Windows handles by calling serial->wait_handle,
   nothing ever actually waits on that file descriptor.  */

struct serial_event_state
  {
#ifdef USE_WIN32API
    /* The Windows event object, created with CreateEvent.  */
    HANDLE event;
#else
    /* The write side of the pipe.  The read side is in
       serial->fd.  */
    int write_fd;
#endif
  };

/* Open a new serial event.  */

static int
serial_event_open (struct serial *scb, const char *name)
{
  struct serial_event_state *state;

  state = XNEW (struct serial_event_state);
  scb->state = state;

#ifndef USE_WIN32API
  {
    int fds[2];

    if (gdb_pipe_cloexec (fds) == -1)
      internal_error (__FILE__, __LINE__,
		      "creating serial event pipe failed.");

    fcntl (fds[0], F_SETFL, O_NONBLOCK);
    fcntl (fds[1], F_SETFL, O_NONBLOCK);

    scb->fd = fds[0];
    state->write_fd = fds[1];
  }
#else
  {
    /* A dummy file object that can be wrapped in a file descriptor.
       We don't need to store this handle because closing the file
       descriptor automatically closes this.  */
    HANDLE dummy_file;

    /* A manual-reset event.  */
    state->event = CreateEvent (0, TRUE, FALSE, 0);

    /* The dummy file handle.  Created just so we have something
       wrappable in a file descriptor.  */
    dummy_file = CreateFile ("nul", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
    scb->fd = _open_osfhandle ((intptr_t) dummy_file, 0);
  }
#endif

  return 0;
}

static void
serial_event_close (struct serial *scb)
{
  struct serial_event_state *state = (struct serial_event_state *) scb->state;

  close (scb->fd);
#ifndef USE_WIN32API
  close (state->write_fd);
#else
  CloseHandle (state->event);
#endif

  scb->fd = -1;

  xfree (state);
  scb->state = NULL;
}

#ifdef USE_WIN32API

/* Implementation of the wait_handle method.  Returns the native
   Windows event object handle.  */

static void
serial_event_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
{
  struct serial_event_state *state = (struct serial_event_state *) scb->state;

  *read = state->event;
}

#endif

/* The serial_ops for struct serial_event objects.  Note we never
   register this serial type with serial_add_interface, because this
   is internal implementation detail never to be used by remote
   targets for protocol transport.  */

static const struct serial_ops serial_event_ops =
{
  "event",
  serial_event_open,
  serial_event_close,
  NULL, /* fdopen */
  NULL, /* readchar */
  NULL, /* write */
  NULL, /* flush_output */
  NULL, /* flush_input */
  NULL, /* send_break */
  NULL, /* go_raw */
  NULL, /* get_tty_state */
  NULL, /* copy_tty_state */
  NULL, /* set_tty_state */
  NULL, /* print_tty_state */
  NULL, /* setbaudrate */
  NULL, /* setstopbits */
  NULL, /* setparity */
  NULL, /* drain_output */
  NULL, /* async */
  NULL, /* read_prim */
  NULL, /* write_prim */
  NULL, /* avail */
#ifdef USE_WIN32API
  serial_event_wait_handle,
#endif
};

/* See ser-event.h.  */

struct serial_event *
make_serial_event (void)
{
  return (struct serial_event *) serial_open_ops (&serial_event_ops);
}

/* See ser-event.h.  */

int
serial_event_fd (struct serial_event *event)
{
  struct serial *ser = (struct serial *) event;

  return ser->fd;
}

/* See ser-event.h.  */

void
serial_event_set (struct serial_event *event)
{
  struct serial *ser = (struct serial *) event;
  struct serial_event_state *state = (struct serial_event_state *) ser->state;
#ifndef USE_WIN32API
  int r;
  char c = '+';		/* Anything.  */

  do
    {
      r = write (state->write_fd, &c, 1);
    }
  while (r < 0 && errno == EINTR);
#else
  SetEvent (state->event);
#endif
}

/* See ser-event.h.  */

void
serial_event_clear (struct serial_event *event)
{
  struct serial *ser = (struct serial *) event;
#ifndef USE_WIN32API
  int r;

  do
    {
      char c;

      r = read (ser->fd, &c, 1);
    }
  while (r > 0 || (r < 0 && errno == EINTR));
#else
  struct serial_event_state *state = (struct serial_event_state *) ser->state;
  ResetEvent (state->event);
#endif
}



/* 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;

#if CXX_STD_THREAD

/* Mutex to hold when handling runnable_event or runnables.  */

static std::mutex runnable_mutex;

#endif

/* 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.  */
  {
#if CXX_STD_THREAD
    std::lock_guard<std::mutex> lock (runnable_mutex);
#endif

    /* 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 (...)
	{
	  /* Ignore exceptions in the callback.  */
	}
    }
}

/* See ser-event.h.  */

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

void
_initialize_ser_event ()
{
  runnable_event = make_serial_event ();
  add_file_handler (serial_event_fd (runnable_event), run_events, nullptr);
}
