/* Serial interface for local (hardwired) serial ports on Windows systems

   Copyright (C) 2006
   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 2 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, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

#include "defs.h"
#include "serial.h"
#include "ser-base.h"
#include "ser-tcp.h"

#include <windows.h>
#include <conio.h>

#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>

#include "gdb_assert.h"
#include "gdb_string.h"

void _initialize_ser_windows (void);

struct ser_windows_state
{
  int in_progress;
  OVERLAPPED ov;
  DWORD lastCommMask;
  HANDLE except_event;
};

/* Open up a real live device for serial I/O.  */

static int
ser_windows_open (struct serial *scb, const char *name)
{
  HANDLE h;
  struct ser_windows_state *state;
  COMMTIMEOUTS timeouts;

  /* Only allow COM ports.  */
  if (strncmp (name, "COM", 3) != 0)
    {
      errno = ENOENT;
      return -1;
    }

  h = CreateFile (name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
		  OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
  if (h == INVALID_HANDLE_VALUE)
    {
      errno = ENOENT;
      return -1;
    }

  scb->fd = _open_osfhandle ((long) h, O_RDWR);
  if (scb->fd < 0)
    {
      errno = ENOENT;
      return -1;
    }

  if (!SetCommMask (h, EV_RXCHAR))
    {
      errno = EINVAL;
      return -1;
    }

  timeouts.ReadIntervalTimeout = MAXDWORD;
  timeouts.ReadTotalTimeoutConstant = 0;
  timeouts.ReadTotalTimeoutMultiplier = 0;
  timeouts.WriteTotalTimeoutConstant = 0;
  timeouts.WriteTotalTimeoutMultiplier = 0;
  if (!SetCommTimeouts (h, &timeouts))
    {
      errno = EINVAL;
      return -1;
    }

  state = xmalloc (sizeof (struct ser_windows_state));
  memset (state, 0, sizeof (struct ser_windows_state));
  scb->state = state;

  /* Create a manual reset event to watch the input buffer.  */
  state->ov.hEvent = CreateEvent (0, TRUE, FALSE, 0);

  /* Create a (currently unused) handle to record exceptions.  */
  state->except_event = CreateEvent (0, TRUE, FALSE, 0);

  return 0;
}

/* Wait for the output to drain away, as opposed to flushing (discarding)
   it.  */

static int
ser_windows_drain_output (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  return (FlushFileBuffers (h) != 0) ? 0 : -1;
}

static int
ser_windows_flush_output (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  return (PurgeComm (h, PURGE_TXCLEAR) != 0) ? 0 : -1;
}

static int
ser_windows_flush_input (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  return (PurgeComm (h, PURGE_RXCLEAR) != 0) ? 0 : -1;
}

static int
ser_windows_send_break (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  if (SetCommBreak (h) == 0)
    return -1;

  /* Delay for 250 milliseconds.  */
  Sleep (250);

  if (ClearCommBreak (h))
    return -1;

  return 0;
}

static void
ser_windows_raw (struct serial *scb)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
  DCB state;

  if (GetCommState (h, &state) == 0)
    return;

  state.fParity = FALSE;
  state.fOutxCtsFlow = FALSE;
  state.fOutxDsrFlow = FALSE;
  state.fDtrControl = DTR_CONTROL_ENABLE;
  state.fDsrSensitivity = FALSE;
  state.fOutX = FALSE;
  state.fInX = FALSE;
  state.fNull = FALSE;
  state.fAbortOnError = FALSE;
  state.ByteSize = 8;
  state.Parity = NOPARITY;

  scb->current_timeout = 0;

  if (SetCommState (h, &state) == 0)
    warning (_("SetCommState failed\n"));
}

static int
ser_windows_setstopbits (struct serial *scb, int num)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
  DCB state;

  if (GetCommState (h, &state) == 0)
    return -1;

  switch (num)
    {
    case SERIAL_1_STOPBITS:
      state.StopBits = ONESTOPBIT;
      break;
    case SERIAL_1_AND_A_HALF_STOPBITS:
      state.StopBits = ONE5STOPBITS;
      break;
    case SERIAL_2_STOPBITS:
      state.StopBits = TWOSTOPBITS;
      break;
    default:
      return 1;
    }

  return (SetCommState (h, &state) != 0) ? 0 : -1;
}

static int
ser_windows_setbaudrate (struct serial *scb, int rate)
{
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
  DCB state;

  if (GetCommState (h, &state) == 0)
    return -1;

  state.BaudRate = rate;

  return (SetCommState (h, &state) != 0) ? 0 : -1;
}

static void
ser_windows_close (struct serial *scb)
{
  struct ser_windows_state *state;

  /* Stop any pending selects.  */
  CancelIo ((HANDLE) _get_osfhandle (scb->fd));
  state = scb->state;
  CloseHandle (state->ov.hEvent);
  CloseHandle (state->except_event);

  if (scb->fd < 0)
    return;

  close (scb->fd);
  scb->fd = -1;

  xfree (scb->state);
}

static void
ser_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
{
  struct ser_windows_state *state;
  COMSTAT status;
  DWORD errors;
  HANDLE h = (HANDLE) _get_osfhandle (scb->fd);

  state = scb->state;

  *except = state->except_event;
  *read = state->ov.hEvent;

  if (state->in_progress)
    return;

  /* Reset the mask - we are only interested in any characters which
     arrive after this point, not characters which might have arrived
     and already been read.  */

  /* This really, really shouldn't be necessary - just the second one.
     But otherwise an internal flag for EV_RXCHAR does not get
     cleared, and we get a duplicated event, if the last batch
     of characters included at least two arriving close together.  */
  if (!SetCommMask (h, 0))
    warning (_("ser_windows_wait_handle: reseting mask failed"));

  if (!SetCommMask (h, EV_RXCHAR))
    warning (_("ser_windows_wait_handle: reseting mask failed (2)"));

  /* There's a potential race condition here; we must check cbInQue
     and not wait if that's nonzero.  */

  ClearCommError (h, &errors, &status);
  if (status.cbInQue > 0)
    {
      SetEvent (state->ov.hEvent);
      return;
    }

  state->in_progress = 1;
  ResetEvent (state->ov.hEvent);
  state->lastCommMask = -2;
  if (WaitCommEvent (h, &state->lastCommMask, &state->ov))
    {
      gdb_assert (state->lastCommMask & EV_RXCHAR);
      SetEvent (state->ov.hEvent);
    }
  else
    gdb_assert (GetLastError () == ERROR_IO_PENDING);
}

static int
ser_windows_read_prim (struct serial *scb, size_t count)
{
  struct ser_windows_state *state;
  OVERLAPPED ov;
  DWORD bytes_read, bytes_read_tmp;
  HANDLE h;
  gdb_byte *p;

  state = scb->state;
  if (state->in_progress)
    {
      WaitForSingleObject (state->ov.hEvent, INFINITE);
      state->in_progress = 0;
      ResetEvent (state->ov.hEvent);
    }

  memset (&ov, 0, sizeof (OVERLAPPED));
  ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
  h = (HANDLE) _get_osfhandle (scb->fd);

  if (!ReadFile (h, scb->buf, /* count */ 1, &bytes_read, &ov))
    {
      if (GetLastError () != ERROR_IO_PENDING
	  || !GetOverlappedResult (h, &ov, &bytes_read, TRUE))
	bytes_read = -1;
    }

  CloseHandle (ov.hEvent);
  return bytes_read;
}

static int
ser_windows_write_prim (struct serial *scb, const void *buf, size_t len)
{
  struct ser_windows_state *state;
  OVERLAPPED ov;
  DWORD bytes_written;
  HANDLE h;

  memset (&ov, 0, sizeof (OVERLAPPED));
  ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
  h = (HANDLE) _get_osfhandle (scb->fd);
  if (!WriteFile (h, buf, len, &bytes_written, &ov))
    {
      if (GetLastError () != ERROR_IO_PENDING
	  || !GetOverlappedResult (h, &ov, &bytes_written, TRUE))
	bytes_written = -1;
    }

  CloseHandle (ov.hEvent);
  return bytes_written;
}

struct ser_console_state
{
  HANDLE read_event;
  HANDLE except_event;

  HANDLE start_select;
  HANDLE stop_select;
  HANDLE exit_select;
  HANDLE have_stopped;

  HANDLE thread;
};

static DWORD WINAPI
console_select_thread (void *arg)
{
  struct serial *scb = arg;
  struct ser_console_state *state;
  int event_index;
  HANDLE h;

  state = scb->state;
  h = (HANDLE) _get_osfhandle (scb->fd);

  while (1)
    {
      HANDLE wait_events[2];
      INPUT_RECORD record;
      DWORD n_records;

      SetEvent (state->have_stopped);

      wait_events[0] = state->start_select;
      wait_events[1] = state->exit_select;

      if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
	return 0;

      ResetEvent (state->have_stopped);

    retry:
      wait_events[0] = state->stop_select;
      wait_events[1] = h;

      event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);

      if (event_index == WAIT_OBJECT_0
	  || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
	continue;

      if (event_index != WAIT_OBJECT_0 + 1)
	{
	  /* Wait must have failed; assume an error has occured, e.g.
	     the handle has been closed.  */
	  SetEvent (state->except_event);
	  continue;
	}

      /* We've got a pending event on the console.  See if it's
	 of interest.  */
      if (!PeekConsoleInput (h, &record, 1, &n_records) || n_records != 1)
	{
	  /* Something went wrong.  Maybe the console is gone.  */
	  SetEvent (state->except_event);
	  continue;
	}

      if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
	{
	  WORD keycode = record.Event.KeyEvent.wVirtualKeyCode;

	  /* Ignore events containing only control keys.  We must
	     recognize "enhanced" keys which we are interested in
	     reading via getch, if they do not map to ASCII.  But we
	     do not want to report input available for e.g. the
	     control key alone.  */

	  if (record.Event.KeyEvent.uChar.AsciiChar != 0
	      || keycode == VK_PRIOR
	      || keycode == VK_NEXT
	      || keycode == VK_END
	      || keycode == VK_HOME
	      || keycode == VK_LEFT
	      || keycode == VK_UP
	      || keycode == VK_RIGHT
	      || keycode == VK_DOWN
	      || keycode == VK_INSERT
	      || keycode == VK_DELETE)
	    {
	      /* This is really a keypress.  */
	      SetEvent (state->read_event);
	      continue;
	    }
	}

      /* Otherwise discard it and wait again.  */
      ReadConsoleInput (h, &record, 1, &n_records);
      goto retry;
    }
}

static int
fd_is_pipe (int fd)
{
  if (PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, NULL, NULL))
    return 1;
  else
    return 0;
}

static DWORD WINAPI
pipe_select_thread (void *arg)
{
  struct serial *scb = arg;
  struct ser_console_state *state;
  int event_index;
  HANDLE h;

  state = scb->state;
  h = (HANDLE) _get_osfhandle (scb->fd);

  while (1)
    {
      HANDLE wait_events[2];
      DWORD n_avail;

      SetEvent (state->have_stopped);

      wait_events[0] = state->start_select;
      wait_events[1] = state->exit_select;

      if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
	return 0;

      ResetEvent (state->have_stopped);

    retry:
      if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL))
	{
	  SetEvent (state->except_event);
	  continue;
	}

      if (n_avail > 0)
	{
	  SetEvent (state->read_event);
	  continue;
	}

      /* Delay 10ms before checking again, but allow the stop event
	 to wake us.  */
      if (WaitForSingleObject (state->stop_select, 10) == WAIT_OBJECT_0)
	continue;

      goto retry;
    }
}

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

  if (state == NULL)
    {
      DWORD threadId;
      int is_tty;

      is_tty = isatty (scb->fd);
      if (!is_tty && !fd_is_pipe (scb->fd))
	{
	  *read = NULL;
	  *except = NULL;
	  return;
	}

      state = xmalloc (sizeof (struct ser_console_state));
      memset (state, 0, sizeof (struct ser_console_state));
      scb->state = state;

      /* Create auto reset events to wake, stop, and exit the select
	 thread.  */
      state->start_select = CreateEvent (0, FALSE, FALSE, 0);
      state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
      state->exit_select = CreateEvent (0, FALSE, FALSE, 0);

      /* Create a manual reset event to signal whether the thread is
	 stopped.  This must be manual reset, because we may wait on
	 it multiple times without ever starting the thread.  */
      state->have_stopped = CreateEvent (0, TRUE, FALSE, 0);

      /* Create our own events to report read and exceptions separately.  */
      state->read_event = CreateEvent (0, FALSE, FALSE, 0);
      state->except_event = CreateEvent (0, FALSE, FALSE, 0);

      if (is_tty)
	state->thread = CreateThread (NULL, 0, console_select_thread, scb, 0,
				      &threadId);
      else
	state->thread = CreateThread (NULL, 0, pipe_select_thread, scb, 0,
				      &threadId);
    }

  *read = state->read_event;
  *except = state->except_event;

  /* Start from a blank state.  */
  ResetEvent (state->read_event);
  ResetEvent (state->except_event);
  ResetEvent (state->stop_select);

  /* First check for a key already in the buffer.  If there is one,
     we don't need a thread.  This also catches the second key of
     multi-character returns from getch, for instance for arrow
     keys.  The second half is in a C library internal buffer,
     and PeekConsoleInput will not find it.  */
  if (_kbhit ())
    {
      SetEvent (state->read_event);
      return;
    }

  /* Otherwise, start the select thread.  */
  SetEvent (state->start_select);
}

static void
ser_console_done_wait_handle (struct serial *scb)
{
  struct ser_console_state *state = scb->state;

  if (state == NULL)
    return;

  SetEvent (state->stop_select);
  WaitForSingleObject (state->have_stopped, INFINITE);
}

static void
ser_console_close (struct serial *scb)
{
  struct ser_console_state *state = scb->state;

  if (scb->state)
    {
      SetEvent (state->exit_select);

      WaitForSingleObject (state->thread, INFINITE);

      CloseHandle (state->start_select);
      CloseHandle (state->stop_select);
      CloseHandle (state->exit_select);
      CloseHandle (state->have_stopped);

      CloseHandle (state->read_event);
      CloseHandle (state->except_event);

      xfree (scb->state);
    }
}

struct ser_console_ttystate
{
  int is_a_tty;
};

static serial_ttystate
ser_console_get_tty_state (struct serial *scb)
{
  if (isatty (scb->fd))
    {
      struct ser_console_ttystate *state;
      state = (struct ser_console_ttystate *) xmalloc (sizeof *state);
      state->is_a_tty = 1;
      return state;
    }
  else
    return NULL;
}

struct pipe_state
{
  /* Since we use the pipe_select_thread for our select emulation,
     we need to place the state structure it requires at the front
     of our state.  */
  struct ser_console_state wait;

  /* The pex obj for our (one-stage) pipeline.  */
  struct pex_obj *pex;

  /* Streams for the pipeline's input and output.  */
  FILE *input, *output;
};

static struct pipe_state *
make_pipe_state (void)
{
  struct pipe_state *ps = XMALLOC (struct pipe_state);

  memset (ps, 0, sizeof (*ps));
  ps->wait.read_event = INVALID_HANDLE_VALUE;
  ps->wait.except_event = INVALID_HANDLE_VALUE;
  ps->wait.start_select = INVALID_HANDLE_VALUE;
  ps->wait.stop_select = INVALID_HANDLE_VALUE;

  return ps;
}

static void
free_pipe_state (struct pipe_state *ps)
{
  int saved_errno = errno;

  if (ps->wait.read_event != INVALID_HANDLE_VALUE)
    CloseHandle (ps->wait.read_event);
  if (ps->wait.except_event != INVALID_HANDLE_VALUE)
    CloseHandle (ps->wait.except_event);
  if (ps->wait.start_select != INVALID_HANDLE_VALUE)
    CloseHandle (ps->wait.start_select);

  /* If we have a select thread running, let the select thread free
     the stop event.  */
  if (ps->wait.stop_select != INVALID_HANDLE_VALUE)
    SetEvent (ps->wait.stop_select);

  /* Close the pipe to the child.  We must close the pipe before
     calling pex_free because pex_free will wait for the child to exit
     and the child will not exit until the pipe is closed.  */
  if (ps->input)
    fclose (ps->input);
  if (ps->pex)
    pex_free (ps->pex);
  /* pex_free closes ps->output.  */

  xfree (ps);

  errno = saved_errno;
}

static void
cleanup_pipe_state (void *untyped)
{
  struct pipe_state *ps = untyped;

  free_pipe_state (ps);
}

static int
pipe_windows_open (struct serial *scb, const char *name)
{
  char **argv = buildargv (name);
  struct cleanup *back_to = make_cleanup_freeargv (argv);
  if (! argv[0] || argv[0][0] == '\0')
    error ("missing child command");

  struct pipe_state *ps = make_pipe_state ();
  make_cleanup (cleanup_pipe_state, ps);

  ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
  if (! ps->pex)
    goto fail;
  ps->input = pex_input_pipe (ps->pex, 1);
  if (! ps->input)
    goto fail;

  {
    int err;
    const char *err_msg
      = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT,
                 argv[0], argv, NULL, NULL,
                 &err);

    if (err_msg)
      {
        /* Our caller expects us to return -1, but all they'll do with
           it generally is print the message based on errno.  We have
           all the same information here, plus err_msg provided by
           pex_run, so we just raise the error here.  */
        if (err)
          error ("error starting child process '%s': %s: %s",
                 name, err_msg, safe_strerror (err));
        else
          error ("error starting child process '%s': %s",
                 name, err_msg);
      }
  }

  ps->output = pex_read_output (ps->pex, 1);
  if (! ps->output)
    goto fail;

  scb->fd = fileno (ps->output);
  scb->state = (void *) ps;

  discard_cleanups (back_to);
  return 0;

 fail:
  do_cleanups (back_to);
  return -1;
}


static void
pipe_windows_close (struct serial *scb)
{
  struct pipe_state *ps = scb->state;

  /* In theory, we should try to kill the subprocess here, but the pex
     interface doesn't give us enough information to do that.  Usually
     closing the input pipe will get the message across.  */

  free_pipe_state (ps);
}


static int
pipe_windows_read (struct serial *scb, size_t count)
{
  HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd);
  if (pipeline_out == INVALID_HANDLE_VALUE)
    return -1;

  DWORD available;
  if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
    return -1;

  if (count > available)
    count = available;

  DWORD bytes_read;
  if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
    return -1;

  return bytes_read;
}


static int
pipe_windows_write (struct serial *scb, const void *buf, size_t count)
{
  struct pipe_state *ps = scb->state;
  int pipeline_in_fd = fileno (ps->input);
  if (pipeline_in_fd < 0)
    return -1;

  HANDLE pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
  if (pipeline_in == INVALID_HANDLE_VALUE)
    return -1;

  DWORD written;
  if (! WriteFile (pipeline_in, buf, count, &written, NULL))
    return -1;

  return written;
}


static void
pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
{
  struct pipe_state *ps = scb->state;

  /* Have we allocated our events yet?  */
  if (ps->wait.read_event == INVALID_HANDLE_VALUE)
    {
      DWORD threadId;

      /* Create auto reset events to wake and terminate the select thread.  */
      ps->wait.start_select = CreateEvent (0, FALSE, FALSE, 0);
      ps->wait.stop_select = CreateEvent (0, FALSE, FALSE, 0);

      /* Create our own events to report read and exceptions separately.
	 The exception event is currently never used.  */
      ps->wait.read_event = CreateEvent (0, FALSE, FALSE, 0);
      ps->wait.except_event = CreateEvent (0, FALSE, FALSE, 0);

      /* Start the select thread.  */
      CreateThread (NULL, 0, pipe_select_thread, scb, 0, &threadId);
    }

  ResetEvent (ps->wait.read_event);
  ResetEvent (ps->wait.except_event);

  SetEvent (ps->wait.start_select);

  *read = ps->wait.read_event;
  *except = ps->wait.except_event;
}


struct net_windows_state
{
  HANDLE read_event;
  HANDLE except_event;

  HANDLE start_select;
  HANDLE stop_select;
  HANDLE exit_select;
  HANDLE have_stopped;

  HANDLE sock_event;

  HANDLE thread;
};

static DWORD WINAPI
net_windows_select_thread (void *arg)
{
  struct serial *scb = arg;
  struct net_windows_state *state, state_copy;
  int event_index;

  state = scb->state;

  while (1)
    {
      HANDLE wait_events[2];
      WSANETWORKEVENTS events;

      SetEvent (state->have_stopped);

      wait_events[0] = state->start_select;
      wait_events[1] = state->exit_select;

      if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
	return 0;

      ResetEvent (state->have_stopped);

      wait_events[0] = state->stop_select;
      wait_events[1] = state->sock_event;

      event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);

      if (event_index == WAIT_OBJECT_0
	  || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
	continue;

      if (event_index != WAIT_OBJECT_0 + 1)
	{
	  /* Some error has occured.  Assume that this is an error
	     condition.  */
	  SetEvent (state->except_event);
	  continue;
	}

      /* Enumerate the internal network events, and reset the object that
	 signalled us to catch the next event.  */
      WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);

      gdb_assert (events.lNetworkEvents & (FD_READ | FD_CLOSE));

      if (events.lNetworkEvents & FD_READ)
	SetEvent (state->read_event);

      if (events.lNetworkEvents & FD_CLOSE)
	SetEvent (state->except_event);
    }
}

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

  /* Start from a clean slate.  */
  ResetEvent (state->read_event);
  ResetEvent (state->except_event);
  ResetEvent (state->stop_select);

  *read = state->read_event;
  *except = state->except_event;

  /* Check any pending events.  This both avoids starting the thread
     unnecessarily, and handles stray FD_READ events (see below).  */
  if (WaitForSingleObject (state->sock_event, 0) == WAIT_OBJECT_0)
    {
      WSANETWORKEVENTS events;
      int any = 0;

      /* Enumerate the internal network events, and reset the object that
	 signalled us to catch the next event.  */
      WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);

      /* You'd think that FD_READ or FD_CLOSE would be set here.  But,
	 sometimes, neither is.  I suspect that the FD_READ is set and
	 the corresponding event signalled while recv is running, and
	 the FD_READ is then lowered when recv consumes all the data,
	 but there's no way to un-signal the event.  This isn't a
	 problem for the call in net_select_thread, since any new
	 events after this point will not have been drained by recv.
	 It just means that we can't have the obvious assert here.  */

      /* If there is a read event, it might be still valid, or it might
	 not be - it may have been signalled before we last called
	 recv.  Double-check that there is data.  */
      if (events.lNetworkEvents & FD_READ)
	{
	  unsigned long available;

	  if (ioctlsocket (scb->fd, FIONREAD, &available) == 0
	      && available > 0)
	    {
	      SetEvent (state->read_event);
	      any = 1;
	    }
	  else
	    /* Oops, no data.  This call to recv will cause future
	       data to retrigger the event, e.g. while we are
	       in net_select_thread.  */
	    recv (scb->fd, NULL, 0, 0);
	}

      /* If there's a close event, then record it - it is obviously
	 still valid, and it will not be resignalled.  */
      if (events.lNetworkEvents & FD_CLOSE)
	{
	  SetEvent (state->except_event);
	  any = 1;
	}

      /* If we set either handle, there's no need to wake the thread.  */
      if (any)
	return;
    }

  /* Start the select thread.  */
  SetEvent (state->start_select);
}

static void
net_windows_done_wait_handle (struct serial *scb)
{
  struct net_windows_state *state = scb->state;

  SetEvent (state->stop_select);
  WaitForSingleObject (state->have_stopped, INFINITE);
}

static int
net_windows_open (struct serial *scb, const char *name)
{
  struct net_windows_state *state;
  int ret;
  DWORD threadId;

  ret = net_open (scb, name);
  if (ret != 0)
    return ret;

  state = xmalloc (sizeof (struct net_windows_state));
  memset (state, 0, sizeof (struct net_windows_state));
  scb->state = state;

  /* Create auto reset events to wake, stop, and exit the select
     thread.  */
  state->start_select = CreateEvent (0, FALSE, FALSE, 0);
  state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
  state->exit_select = CreateEvent (0, FALSE, FALSE, 0);

  /* Create a manual reset event to signal whether the thread is
     stopped.  This must be manual reset, because we may wait on
     it multiple times without ever starting the thread.  */
  state->have_stopped = CreateEvent (0, TRUE, FALSE, 0);

  /* Associate an event with the socket.  */
  state->sock_event = CreateEvent (0, TRUE, FALSE, 0);
  WSAEventSelect (scb->fd, state->sock_event, FD_READ | FD_CLOSE);

  /* Create our own events to report read and close separately.  */
  state->read_event = CreateEvent (0, FALSE, FALSE, 0);
  state->except_event = CreateEvent (0, FALSE, FALSE, 0);

  /* And finally start the select thread.  */
  state->thread = CreateThread (NULL, 0, net_windows_select_thread, scb, 0,
				&threadId);

  return 0;
}


static void
net_windows_close (struct serial *scb)
{
  struct net_windows_state *state = scb->state;

  SetEvent (state->exit_select);
  WaitForSingleObject (state->thread, INFINITE);

  CloseHandle (state->read_event);
  CloseHandle (state->except_event);

  CloseHandle (state->start_select);
  CloseHandle (state->stop_select);
  CloseHandle (state->exit_select);
  CloseHandle (state->have_stopped);

  CloseHandle (state->sock_event);

  xfree (scb->state);

  net_close (scb);
}

void
_initialize_ser_windows (void)
{
  WSADATA wsa_data;
  struct serial_ops *ops;

  /* First register the serial port driver.  */

  ops = XMALLOC (struct serial_ops);
  memset (ops, 0, sizeof (struct serial_ops));
  ops->name = "hardwire";
  ops->next = 0;
  ops->open = ser_windows_open;
  ops->close = ser_windows_close;

  ops->flush_output = ser_windows_flush_output;
  ops->flush_input = ser_windows_flush_input;
  ops->send_break = ser_windows_send_break;

  /* These are only used for stdin; we do not need them for serial
     ports, so supply the standard dummies.  */
  ops->get_tty_state = ser_base_get_tty_state;
  ops->set_tty_state = ser_base_set_tty_state;
  ops->print_tty_state = ser_base_print_tty_state;
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;

  ops->go_raw = ser_windows_raw;
  ops->setbaudrate = ser_windows_setbaudrate;
  ops->setstopbits = ser_windows_setstopbits;
  ops->drain_output = ser_windows_drain_output;
  ops->readchar = ser_base_readchar;
  ops->write = ser_base_write;
  ops->async = ser_base_async;
  ops->read_prim = ser_windows_read_prim;
  ops->write_prim = ser_windows_write_prim;
  ops->wait_handle = ser_windows_wait_handle;

  serial_add_interface (ops);

  /* Next create the dummy serial driver used for terminals.  We only
     provide the TTY-related methods.  */

  ops = XMALLOC (struct serial_ops);
  memset (ops, 0, sizeof (struct serial_ops));

  ops->name = "terminal";
  ops->next = 0;

  ops->close = ser_console_close;
  ops->get_tty_state = ser_console_get_tty_state;
  ops->set_tty_state = ser_base_set_tty_state;
  ops->print_tty_state = ser_base_print_tty_state;
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
  ops->drain_output = ser_base_drain_output;
  ops->wait_handle = ser_console_wait_handle;
  ops->done_wait_handle = ser_console_done_wait_handle;

  serial_add_interface (ops);

  /* The pipe interface.  */

  ops = XMALLOC (struct serial_ops);
  memset (ops, 0, sizeof (struct serial_ops));
  ops->name = "pipe";
  ops->next = 0;
  ops->open = pipe_windows_open;
  ops->close = pipe_windows_close;
  ops->readchar = ser_base_readchar;
  ops->write = ser_base_write;
  ops->flush_output = ser_base_flush_output;
  ops->flush_input = ser_base_flush_input;
  ops->send_break = ser_base_send_break;
  ops->go_raw = ser_base_raw;
  ops->get_tty_state = ser_base_get_tty_state;
  ops->set_tty_state = ser_base_set_tty_state;
  ops->print_tty_state = ser_base_print_tty_state;
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
  ops->setbaudrate = ser_base_setbaudrate;
  ops->setstopbits = ser_base_setstopbits;
  ops->drain_output = ser_base_drain_output;
  ops->async = ser_base_async;
  ops->read_prim = pipe_windows_read;
  ops->write_prim = pipe_windows_write;
  ops->wait_handle = pipe_wait_handle;

  serial_add_interface (ops);

  /* If WinSock works, register the TCP/UDP socket driver.  */

  if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
    /* WinSock is unavailable.  */
    return;

  ops = XMALLOC (struct serial_ops);
  memset (ops, 0, sizeof (struct serial_ops));
  ops->name = "tcp";
  ops->next = 0;
  ops->open = net_windows_open;
  ops->close = net_windows_close;
  ops->readchar = ser_base_readchar;
  ops->write = ser_base_write;
  ops->flush_output = ser_base_flush_output;
  ops->flush_input = ser_base_flush_input;
  ops->send_break = ser_base_send_break;
  ops->go_raw = ser_base_raw;
  ops->get_tty_state = ser_base_get_tty_state;
  ops->set_tty_state = ser_base_set_tty_state;
  ops->print_tty_state = ser_base_print_tty_state;
  ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
  ops->setbaudrate = ser_base_setbaudrate;
  ops->setstopbits = ser_base_setstopbits;
  ops->drain_output = ser_base_drain_output;
  ops->async = ser_base_async;
  ops->read_prim = net_read_prim;
  ops->write_prim = net_write_prim;
  ops->wait_handle = net_windows_wait_handle;
  ops->done_wait_handle = net_windows_done_wait_handle;
  serial_add_interface (ops);
}
