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

    if (state == NULL)
    {
        thread_fn_type thread_fn;
        int is_tty;

        is_tty = isatty (scb->fd);
        if (!is_tty && !fd_is_file (scb->fd) && !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;

        if (is_tty)
            thread_fn = console_select_thread;
        else if (fd_is_pipe (scb->fd))
            thread_fn = pipe_select_thread;
        else
            thread_fn = file_select_thread;

        create_select_thread (thread_fn, scb, state);
    }

    *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.  */
    start_select_thread (state);
}
Esempio n. 2
0
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);
}