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); }
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); }