No empty .Rs/.Re
[netbsd-mini2440.git] / gnu / dist / gdb6 / gdb / ser-mingw.c
blob79e186b842d0ab812082e3f3e4d72f1b671cf3af
1 /* Serial interface for local (hardwired) serial ports on Windows systems
3 Copyright (C) 2006
4 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 #include "defs.h"
24 #include "serial.h"
25 #include "ser-base.h"
26 #include "ser-tcp.h"
28 #include <windows.h>
29 #include <conio.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <sys/types.h>
35 #include "gdb_assert.h"
36 #include "gdb_string.h"
38 void _initialize_ser_windows (void);
40 struct ser_windows_state
42 int in_progress;
43 OVERLAPPED ov;
44 DWORD lastCommMask;
45 HANDLE except_event;
48 /* Open up a real live device for serial I/O. */
50 static int
51 ser_windows_open (struct serial *scb, const char *name)
53 HANDLE h;
54 struct ser_windows_state *state;
55 COMMTIMEOUTS timeouts;
57 /* Only allow COM ports. */
58 if (strncmp (name, "COM", 3) != 0)
60 errno = ENOENT;
61 return -1;
64 h = CreateFile (name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
65 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
66 if (h == INVALID_HANDLE_VALUE)
68 errno = ENOENT;
69 return -1;
72 scb->fd = _open_osfhandle ((long) h, O_RDWR);
73 if (scb->fd < 0)
75 errno = ENOENT;
76 return -1;
79 if (!SetCommMask (h, EV_RXCHAR))
81 errno = EINVAL;
82 return -1;
85 timeouts.ReadIntervalTimeout = MAXDWORD;
86 timeouts.ReadTotalTimeoutConstant = 0;
87 timeouts.ReadTotalTimeoutMultiplier = 0;
88 timeouts.WriteTotalTimeoutConstant = 0;
89 timeouts.WriteTotalTimeoutMultiplier = 0;
90 if (!SetCommTimeouts (h, &timeouts))
92 errno = EINVAL;
93 return -1;
96 state = xmalloc (sizeof (struct ser_windows_state));
97 memset (state, 0, sizeof (struct ser_windows_state));
98 scb->state = state;
100 /* Create a manual reset event to watch the input buffer. */
101 state->ov.hEvent = CreateEvent (0, TRUE, FALSE, 0);
103 /* Create a (currently unused) handle to record exceptions. */
104 state->except_event = CreateEvent (0, TRUE, FALSE, 0);
106 return 0;
109 /* Wait for the output to drain away, as opposed to flushing (discarding)
110 it. */
112 static int
113 ser_windows_drain_output (struct serial *scb)
115 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
117 return (FlushFileBuffers (h) != 0) ? 0 : -1;
120 static int
121 ser_windows_flush_output (struct serial *scb)
123 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
125 return (PurgeComm (h, PURGE_TXCLEAR) != 0) ? 0 : -1;
128 static int
129 ser_windows_flush_input (struct serial *scb)
131 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
133 return (PurgeComm (h, PURGE_RXCLEAR) != 0) ? 0 : -1;
136 static int
137 ser_windows_send_break (struct serial *scb)
139 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
141 if (SetCommBreak (h) == 0)
142 return -1;
144 /* Delay for 250 milliseconds. */
145 Sleep (250);
147 if (ClearCommBreak (h))
148 return -1;
150 return 0;
153 static void
154 ser_windows_raw (struct serial *scb)
156 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
157 DCB state;
159 if (GetCommState (h, &state) == 0)
160 return;
162 state.fParity = FALSE;
163 state.fOutxCtsFlow = FALSE;
164 state.fOutxDsrFlow = FALSE;
165 state.fDtrControl = DTR_CONTROL_ENABLE;
166 state.fDsrSensitivity = FALSE;
167 state.fOutX = FALSE;
168 state.fInX = FALSE;
169 state.fNull = FALSE;
170 state.fAbortOnError = FALSE;
171 state.ByteSize = 8;
172 state.Parity = NOPARITY;
174 scb->current_timeout = 0;
176 if (SetCommState (h, &state) == 0)
177 warning (_("SetCommState failed\n"));
180 static int
181 ser_windows_setstopbits (struct serial *scb, int num)
183 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
184 DCB state;
186 if (GetCommState (h, &state) == 0)
187 return -1;
189 switch (num)
191 case SERIAL_1_STOPBITS:
192 state.StopBits = ONESTOPBIT;
193 break;
194 case SERIAL_1_AND_A_HALF_STOPBITS:
195 state.StopBits = ONE5STOPBITS;
196 break;
197 case SERIAL_2_STOPBITS:
198 state.StopBits = TWOSTOPBITS;
199 break;
200 default:
201 return 1;
204 return (SetCommState (h, &state) != 0) ? 0 : -1;
207 static int
208 ser_windows_setbaudrate (struct serial *scb, int rate)
210 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
211 DCB state;
213 if (GetCommState (h, &state) == 0)
214 return -1;
216 state.BaudRate = rate;
218 return (SetCommState (h, &state) != 0) ? 0 : -1;
221 static void
222 ser_windows_close (struct serial *scb)
224 struct ser_windows_state *state;
226 /* Stop any pending selects. */
227 CancelIo ((HANDLE) _get_osfhandle (scb->fd));
228 state = scb->state;
229 CloseHandle (state->ov.hEvent);
230 CloseHandle (state->except_event);
232 if (scb->fd < 0)
233 return;
235 close (scb->fd);
236 scb->fd = -1;
238 xfree (scb->state);
241 static void
242 ser_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
244 struct ser_windows_state *state;
245 COMSTAT status;
246 DWORD errors;
247 HANDLE h = (HANDLE) _get_osfhandle (scb->fd);
249 state = scb->state;
251 *except = state->except_event;
252 *read = state->ov.hEvent;
254 if (state->in_progress)
255 return;
257 /* Reset the mask - we are only interested in any characters which
258 arrive after this point, not characters which might have arrived
259 and already been read. */
261 /* This really, really shouldn't be necessary - just the second one.
262 But otherwise an internal flag for EV_RXCHAR does not get
263 cleared, and we get a duplicated event, if the last batch
264 of characters included at least two arriving close together. */
265 if (!SetCommMask (h, 0))
266 warning (_("ser_windows_wait_handle: reseting mask failed"));
268 if (!SetCommMask (h, EV_RXCHAR))
269 warning (_("ser_windows_wait_handle: reseting mask failed (2)"));
271 /* There's a potential race condition here; we must check cbInQue
272 and not wait if that's nonzero. */
274 ClearCommError (h, &errors, &status);
275 if (status.cbInQue > 0)
277 SetEvent (state->ov.hEvent);
278 return;
281 state->in_progress = 1;
282 ResetEvent (state->ov.hEvent);
283 state->lastCommMask = -2;
284 if (WaitCommEvent (h, &state->lastCommMask, &state->ov))
286 gdb_assert (state->lastCommMask & EV_RXCHAR);
287 SetEvent (state->ov.hEvent);
289 else
290 gdb_assert (GetLastError () == ERROR_IO_PENDING);
293 static int
294 ser_windows_read_prim (struct serial *scb, size_t count)
296 struct ser_windows_state *state;
297 OVERLAPPED ov;
298 DWORD bytes_read, bytes_read_tmp;
299 HANDLE h;
300 gdb_byte *p;
302 state = scb->state;
303 if (state->in_progress)
305 WaitForSingleObject (state->ov.hEvent, INFINITE);
306 state->in_progress = 0;
307 ResetEvent (state->ov.hEvent);
310 memset (&ov, 0, sizeof (OVERLAPPED));
311 ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
312 h = (HANDLE) _get_osfhandle (scb->fd);
314 if (!ReadFile (h, scb->buf, /* count */ 1, &bytes_read, &ov))
316 if (GetLastError () != ERROR_IO_PENDING
317 || !GetOverlappedResult (h, &ov, &bytes_read, TRUE))
318 bytes_read = -1;
321 CloseHandle (ov.hEvent);
322 return bytes_read;
325 static int
326 ser_windows_write_prim (struct serial *scb, const void *buf, size_t len)
328 struct ser_windows_state *state;
329 OVERLAPPED ov;
330 DWORD bytes_written;
331 HANDLE h;
333 memset (&ov, 0, sizeof (OVERLAPPED));
334 ov.hEvent = CreateEvent (0, FALSE, FALSE, 0);
335 h = (HANDLE) _get_osfhandle (scb->fd);
336 if (!WriteFile (h, buf, len, &bytes_written, &ov))
338 if (GetLastError () != ERROR_IO_PENDING
339 || !GetOverlappedResult (h, &ov, &bytes_written, TRUE))
340 bytes_written = -1;
343 CloseHandle (ov.hEvent);
344 return bytes_written;
347 struct ser_console_state
349 HANDLE read_event;
350 HANDLE except_event;
352 HANDLE start_select;
353 HANDLE stop_select;
354 HANDLE exit_select;
355 HANDLE have_stopped;
357 HANDLE thread;
360 static DWORD WINAPI
361 console_select_thread (void *arg)
363 struct serial *scb = arg;
364 struct ser_console_state *state;
365 int event_index;
366 HANDLE h;
368 state = scb->state;
369 h = (HANDLE) _get_osfhandle (scb->fd);
371 while (1)
373 HANDLE wait_events[2];
374 INPUT_RECORD record;
375 DWORD n_records;
377 SetEvent (state->have_stopped);
379 wait_events[0] = state->start_select;
380 wait_events[1] = state->exit_select;
382 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
383 return 0;
385 ResetEvent (state->have_stopped);
387 retry:
388 wait_events[0] = state->stop_select;
389 wait_events[1] = h;
391 event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
393 if (event_index == WAIT_OBJECT_0
394 || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
395 continue;
397 if (event_index != WAIT_OBJECT_0 + 1)
399 /* Wait must have failed; assume an error has occured, e.g.
400 the handle has been closed. */
401 SetEvent (state->except_event);
402 continue;
405 /* We've got a pending event on the console. See if it's
406 of interest. */
407 if (!PeekConsoleInput (h, &record, 1, &n_records) || n_records != 1)
409 /* Something went wrong. Maybe the console is gone. */
410 SetEvent (state->except_event);
411 continue;
414 if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown)
416 WORD keycode = record.Event.KeyEvent.wVirtualKeyCode;
418 /* Ignore events containing only control keys. We must
419 recognize "enhanced" keys which we are interested in
420 reading via getch, if they do not map to ASCII. But we
421 do not want to report input available for e.g. the
422 control key alone. */
424 if (record.Event.KeyEvent.uChar.AsciiChar != 0
425 || keycode == VK_PRIOR
426 || keycode == VK_NEXT
427 || keycode == VK_END
428 || keycode == VK_HOME
429 || keycode == VK_LEFT
430 || keycode == VK_UP
431 || keycode == VK_RIGHT
432 || keycode == VK_DOWN
433 || keycode == VK_INSERT
434 || keycode == VK_DELETE)
436 /* This is really a keypress. */
437 SetEvent (state->read_event);
438 continue;
442 /* Otherwise discard it and wait again. */
443 ReadConsoleInput (h, &record, 1, &n_records);
444 goto retry;
448 static int
449 fd_is_pipe (int fd)
451 if (PeekNamedPipe ((HANDLE) _get_osfhandle (fd), NULL, 0, NULL, NULL, NULL))
452 return 1;
453 else
454 return 0;
457 static DWORD WINAPI
458 pipe_select_thread (void *arg)
460 struct serial *scb = arg;
461 struct ser_console_state *state;
462 int event_index;
463 HANDLE h;
465 state = scb->state;
466 h = (HANDLE) _get_osfhandle (scb->fd);
468 while (1)
470 HANDLE wait_events[2];
471 DWORD n_avail;
473 SetEvent (state->have_stopped);
475 wait_events[0] = state->start_select;
476 wait_events[1] = state->exit_select;
478 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
479 return 0;
481 ResetEvent (state->have_stopped);
483 retry:
484 if (!PeekNamedPipe (h, NULL, 0, NULL, &n_avail, NULL))
486 SetEvent (state->except_event);
487 continue;
490 if (n_avail > 0)
492 SetEvent (state->read_event);
493 continue;
496 /* Delay 10ms before checking again, but allow the stop event
497 to wake us. */
498 if (WaitForSingleObject (state->stop_select, 10) == WAIT_OBJECT_0)
499 continue;
501 goto retry;
505 static void
506 ser_console_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
508 struct ser_console_state *state = scb->state;
510 if (state == NULL)
512 DWORD threadId;
513 int is_tty;
515 is_tty = isatty (scb->fd);
516 if (!is_tty && !fd_is_pipe (scb->fd))
518 *read = NULL;
519 *except = NULL;
520 return;
523 state = xmalloc (sizeof (struct ser_console_state));
524 memset (state, 0, sizeof (struct ser_console_state));
525 scb->state = state;
527 /* Create auto reset events to wake, stop, and exit the select
528 thread. */
529 state->start_select = CreateEvent (0, FALSE, FALSE, 0);
530 state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
531 state->exit_select = CreateEvent (0, FALSE, FALSE, 0);
533 /* Create a manual reset event to signal whether the thread is
534 stopped. This must be manual reset, because we may wait on
535 it multiple times without ever starting the thread. */
536 state->have_stopped = CreateEvent (0, TRUE, FALSE, 0);
538 /* Create our own events to report read and exceptions separately. */
539 state->read_event = CreateEvent (0, FALSE, FALSE, 0);
540 state->except_event = CreateEvent (0, FALSE, FALSE, 0);
542 if (is_tty)
543 state->thread = CreateThread (NULL, 0, console_select_thread, scb, 0,
544 &threadId);
545 else
546 state->thread = CreateThread (NULL, 0, pipe_select_thread, scb, 0,
547 &threadId);
550 *read = state->read_event;
551 *except = state->except_event;
553 /* Start from a blank state. */
554 ResetEvent (state->read_event);
555 ResetEvent (state->except_event);
556 ResetEvent (state->stop_select);
558 /* First check for a key already in the buffer. If there is one,
559 we don't need a thread. This also catches the second key of
560 multi-character returns from getch, for instance for arrow
561 keys. The second half is in a C library internal buffer,
562 and PeekConsoleInput will not find it. */
563 if (_kbhit ())
565 SetEvent (state->read_event);
566 return;
569 /* Otherwise, start the select thread. */
570 SetEvent (state->start_select);
573 static void
574 ser_console_done_wait_handle (struct serial *scb)
576 struct ser_console_state *state = scb->state;
578 if (state == NULL)
579 return;
581 SetEvent (state->stop_select);
582 WaitForSingleObject (state->have_stopped, INFINITE);
585 static void
586 ser_console_close (struct serial *scb)
588 struct ser_console_state *state = scb->state;
590 if (scb->state)
592 SetEvent (state->exit_select);
594 WaitForSingleObject (state->thread, INFINITE);
596 CloseHandle (state->start_select);
597 CloseHandle (state->stop_select);
598 CloseHandle (state->exit_select);
599 CloseHandle (state->have_stopped);
601 CloseHandle (state->read_event);
602 CloseHandle (state->except_event);
604 xfree (scb->state);
608 struct ser_console_ttystate
610 int is_a_tty;
613 static serial_ttystate
614 ser_console_get_tty_state (struct serial *scb)
616 if (isatty (scb->fd))
618 struct ser_console_ttystate *state;
619 state = (struct ser_console_ttystate *) xmalloc (sizeof *state);
620 state->is_a_tty = 1;
621 return state;
623 else
624 return NULL;
627 struct pipe_state
629 /* Since we use the pipe_select_thread for our select emulation,
630 we need to place the state structure it requires at the front
631 of our state. */
632 struct ser_console_state wait;
634 /* The pex obj for our (one-stage) pipeline. */
635 struct pex_obj *pex;
637 /* Streams for the pipeline's input and output. */
638 FILE *input, *output;
641 static struct pipe_state *
642 make_pipe_state (void)
644 struct pipe_state *ps = XMALLOC (struct pipe_state);
646 memset (ps, 0, sizeof (*ps));
647 ps->wait.read_event = INVALID_HANDLE_VALUE;
648 ps->wait.except_event = INVALID_HANDLE_VALUE;
649 ps->wait.start_select = INVALID_HANDLE_VALUE;
650 ps->wait.stop_select = INVALID_HANDLE_VALUE;
652 return ps;
655 static void
656 free_pipe_state (struct pipe_state *ps)
658 int saved_errno = errno;
660 if (ps->wait.read_event != INVALID_HANDLE_VALUE)
661 CloseHandle (ps->wait.read_event);
662 if (ps->wait.except_event != INVALID_HANDLE_VALUE)
663 CloseHandle (ps->wait.except_event);
664 if (ps->wait.start_select != INVALID_HANDLE_VALUE)
665 CloseHandle (ps->wait.start_select);
667 /* If we have a select thread running, let the select thread free
668 the stop event. */
669 if (ps->wait.stop_select != INVALID_HANDLE_VALUE)
670 SetEvent (ps->wait.stop_select);
672 /* Close the pipe to the child. We must close the pipe before
673 calling pex_free because pex_free will wait for the child to exit
674 and the child will not exit until the pipe is closed. */
675 if (ps->input)
676 fclose (ps->input);
677 if (ps->pex)
678 pex_free (ps->pex);
679 /* pex_free closes ps->output. */
681 xfree (ps);
683 errno = saved_errno;
686 static void
687 cleanup_pipe_state (void *untyped)
689 struct pipe_state *ps = untyped;
691 free_pipe_state (ps);
694 static int
695 pipe_windows_open (struct serial *scb, const char *name)
697 char **argv = buildargv (name);
698 struct cleanup *back_to = make_cleanup_freeargv (argv);
699 if (! argv[0] || argv[0][0] == '\0')
700 error ("missing child command");
702 struct pipe_state *ps = make_pipe_state ();
703 make_cleanup (cleanup_pipe_state, ps);
705 ps->pex = pex_init (PEX_USE_PIPES, "target remote pipe", NULL);
706 if (! ps->pex)
707 goto fail;
708 ps->input = pex_input_pipe (ps->pex, 1);
709 if (! ps->input)
710 goto fail;
713 int err;
714 const char *err_msg
715 = pex_run (ps->pex, PEX_SEARCH | PEX_BINARY_INPUT | PEX_BINARY_OUTPUT,
716 argv[0], argv, NULL, NULL,
717 &err);
719 if (err_msg)
721 /* Our caller expects us to return -1, but all they'll do with
722 it generally is print the message based on errno. We have
723 all the same information here, plus err_msg provided by
724 pex_run, so we just raise the error here. */
725 if (err)
726 error ("error starting child process '%s': %s: %s",
727 name, err_msg, safe_strerror (err));
728 else
729 error ("error starting child process '%s': %s",
730 name, err_msg);
734 ps->output = pex_read_output (ps->pex, 1);
735 if (! ps->output)
736 goto fail;
738 scb->fd = fileno (ps->output);
739 scb->state = (void *) ps;
741 discard_cleanups (back_to);
742 return 0;
744 fail:
745 do_cleanups (back_to);
746 return -1;
750 static void
751 pipe_windows_close (struct serial *scb)
753 struct pipe_state *ps = scb->state;
755 /* In theory, we should try to kill the subprocess here, but the pex
756 interface doesn't give us enough information to do that. Usually
757 closing the input pipe will get the message across. */
759 free_pipe_state (ps);
763 static int
764 pipe_windows_read (struct serial *scb, size_t count)
766 HANDLE pipeline_out = (HANDLE) _get_osfhandle (scb->fd);
767 if (pipeline_out == INVALID_HANDLE_VALUE)
768 return -1;
770 DWORD available;
771 if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
772 return -1;
774 if (count > available)
775 count = available;
777 DWORD bytes_read;
778 if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
779 return -1;
781 return bytes_read;
785 static int
786 pipe_windows_write (struct serial *scb, const void *buf, size_t count)
788 struct pipe_state *ps = scb->state;
789 int pipeline_in_fd = fileno (ps->input);
790 if (pipeline_in_fd < 0)
791 return -1;
793 HANDLE pipeline_in = (HANDLE) _get_osfhandle (pipeline_in_fd);
794 if (pipeline_in == INVALID_HANDLE_VALUE)
795 return -1;
797 DWORD written;
798 if (! WriteFile (pipeline_in, buf, count, &written, NULL))
799 return -1;
801 return written;
805 static void
806 pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
808 struct pipe_state *ps = scb->state;
810 /* Have we allocated our events yet? */
811 if (ps->wait.read_event == INVALID_HANDLE_VALUE)
813 DWORD threadId;
815 /* Create auto reset events to wake and terminate the select thread. */
816 ps->wait.start_select = CreateEvent (0, FALSE, FALSE, 0);
817 ps->wait.stop_select = CreateEvent (0, FALSE, FALSE, 0);
819 /* Create our own events to report read and exceptions separately.
820 The exception event is currently never used. */
821 ps->wait.read_event = CreateEvent (0, FALSE, FALSE, 0);
822 ps->wait.except_event = CreateEvent (0, FALSE, FALSE, 0);
824 /* Start the select thread. */
825 CreateThread (NULL, 0, pipe_select_thread, scb, 0, &threadId);
828 ResetEvent (ps->wait.read_event);
829 ResetEvent (ps->wait.except_event);
831 SetEvent (ps->wait.start_select);
833 *read = ps->wait.read_event;
834 *except = ps->wait.except_event;
838 struct net_windows_state
840 HANDLE read_event;
841 HANDLE except_event;
843 HANDLE start_select;
844 HANDLE stop_select;
845 HANDLE exit_select;
846 HANDLE have_stopped;
848 HANDLE sock_event;
850 HANDLE thread;
853 static DWORD WINAPI
854 net_windows_select_thread (void *arg)
856 struct serial *scb = arg;
857 struct net_windows_state *state, state_copy;
858 int event_index;
860 state = scb->state;
862 while (1)
864 HANDLE wait_events[2];
865 WSANETWORKEVENTS events;
867 SetEvent (state->have_stopped);
869 wait_events[0] = state->start_select;
870 wait_events[1] = state->exit_select;
872 if (WaitForMultipleObjects (2, wait_events, FALSE, INFINITE) != WAIT_OBJECT_0)
873 return 0;
875 ResetEvent (state->have_stopped);
877 wait_events[0] = state->stop_select;
878 wait_events[1] = state->sock_event;
880 event_index = WaitForMultipleObjects (2, wait_events, FALSE, INFINITE);
882 if (event_index == WAIT_OBJECT_0
883 || WaitForSingleObject (state->stop_select, 0) == WAIT_OBJECT_0)
884 continue;
886 if (event_index != WAIT_OBJECT_0 + 1)
888 /* Some error has occured. Assume that this is an error
889 condition. */
890 SetEvent (state->except_event);
891 continue;
894 /* Enumerate the internal network events, and reset the object that
895 signalled us to catch the next event. */
896 WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
898 gdb_assert (events.lNetworkEvents & (FD_READ | FD_CLOSE));
900 if (events.lNetworkEvents & FD_READ)
901 SetEvent (state->read_event);
903 if (events.lNetworkEvents & FD_CLOSE)
904 SetEvent (state->except_event);
908 static void
909 net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
911 struct net_windows_state *state = scb->state;
913 /* Start from a clean slate. */
914 ResetEvent (state->read_event);
915 ResetEvent (state->except_event);
916 ResetEvent (state->stop_select);
918 *read = state->read_event;
919 *except = state->except_event;
921 /* Check any pending events. This both avoids starting the thread
922 unnecessarily, and handles stray FD_READ events (see below). */
923 if (WaitForSingleObject (state->sock_event, 0) == WAIT_OBJECT_0)
925 WSANETWORKEVENTS events;
926 int any = 0;
928 /* Enumerate the internal network events, and reset the object that
929 signalled us to catch the next event. */
930 WSAEnumNetworkEvents (scb->fd, state->sock_event, &events);
932 /* You'd think that FD_READ or FD_CLOSE would be set here. But,
933 sometimes, neither is. I suspect that the FD_READ is set and
934 the corresponding event signalled while recv is running, and
935 the FD_READ is then lowered when recv consumes all the data,
936 but there's no way to un-signal the event. This isn't a
937 problem for the call in net_select_thread, since any new
938 events after this point will not have been drained by recv.
939 It just means that we can't have the obvious assert here. */
941 /* If there is a read event, it might be still valid, or it might
942 not be - it may have been signalled before we last called
943 recv. Double-check that there is data. */
944 if (events.lNetworkEvents & FD_READ)
946 unsigned long available;
948 if (ioctlsocket (scb->fd, FIONREAD, &available) == 0
949 && available > 0)
951 SetEvent (state->read_event);
952 any = 1;
954 else
955 /* Oops, no data. This call to recv will cause future
956 data to retrigger the event, e.g. while we are
957 in net_select_thread. */
958 recv (scb->fd, NULL, 0, 0);
961 /* If there's a close event, then record it - it is obviously
962 still valid, and it will not be resignalled. */
963 if (events.lNetworkEvents & FD_CLOSE)
965 SetEvent (state->except_event);
966 any = 1;
969 /* If we set either handle, there's no need to wake the thread. */
970 if (any)
971 return;
974 /* Start the select thread. */
975 SetEvent (state->start_select);
978 static void
979 net_windows_done_wait_handle (struct serial *scb)
981 struct net_windows_state *state = scb->state;
983 SetEvent (state->stop_select);
984 WaitForSingleObject (state->have_stopped, INFINITE);
987 static int
988 net_windows_open (struct serial *scb, const char *name)
990 struct net_windows_state *state;
991 int ret;
992 DWORD threadId;
994 ret = net_open (scb, name);
995 if (ret != 0)
996 return ret;
998 state = xmalloc (sizeof (struct net_windows_state));
999 memset (state, 0, sizeof (struct net_windows_state));
1000 scb->state = state;
1002 /* Create auto reset events to wake, stop, and exit the select
1003 thread. */
1004 state->start_select = CreateEvent (0, FALSE, FALSE, 0);
1005 state->stop_select = CreateEvent (0, FALSE, FALSE, 0);
1006 state->exit_select = CreateEvent (0, FALSE, FALSE, 0);
1008 /* Create a manual reset event to signal whether the thread is
1009 stopped. This must be manual reset, because we may wait on
1010 it multiple times without ever starting the thread. */
1011 state->have_stopped = CreateEvent (0, TRUE, FALSE, 0);
1013 /* Associate an event with the socket. */
1014 state->sock_event = CreateEvent (0, TRUE, FALSE, 0);
1015 WSAEventSelect (scb->fd, state->sock_event, FD_READ | FD_CLOSE);
1017 /* Create our own events to report read and close separately. */
1018 state->read_event = CreateEvent (0, FALSE, FALSE, 0);
1019 state->except_event = CreateEvent (0, FALSE, FALSE, 0);
1021 /* And finally start the select thread. */
1022 state->thread = CreateThread (NULL, 0, net_windows_select_thread, scb, 0,
1023 &threadId);
1025 return 0;
1029 static void
1030 net_windows_close (struct serial *scb)
1032 struct net_windows_state *state = scb->state;
1034 SetEvent (state->exit_select);
1035 WaitForSingleObject (state->thread, INFINITE);
1037 CloseHandle (state->read_event);
1038 CloseHandle (state->except_event);
1040 CloseHandle (state->start_select);
1041 CloseHandle (state->stop_select);
1042 CloseHandle (state->exit_select);
1043 CloseHandle (state->have_stopped);
1045 CloseHandle (state->sock_event);
1047 xfree (scb->state);
1049 net_close (scb);
1052 void
1053 _initialize_ser_windows (void)
1055 WSADATA wsa_data;
1056 struct serial_ops *ops;
1058 /* First register the serial port driver. */
1060 ops = XMALLOC (struct serial_ops);
1061 memset (ops, 0, sizeof (struct serial_ops));
1062 ops->name = "hardwire";
1063 ops->next = 0;
1064 ops->open = ser_windows_open;
1065 ops->close = ser_windows_close;
1067 ops->flush_output = ser_windows_flush_output;
1068 ops->flush_input = ser_windows_flush_input;
1069 ops->send_break = ser_windows_send_break;
1071 /* These are only used for stdin; we do not need them for serial
1072 ports, so supply the standard dummies. */
1073 ops->get_tty_state = ser_base_get_tty_state;
1074 ops->set_tty_state = ser_base_set_tty_state;
1075 ops->print_tty_state = ser_base_print_tty_state;
1076 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1078 ops->go_raw = ser_windows_raw;
1079 ops->setbaudrate = ser_windows_setbaudrate;
1080 ops->setstopbits = ser_windows_setstopbits;
1081 ops->drain_output = ser_windows_drain_output;
1082 ops->readchar = ser_base_readchar;
1083 ops->write = ser_base_write;
1084 ops->async = ser_base_async;
1085 ops->read_prim = ser_windows_read_prim;
1086 ops->write_prim = ser_windows_write_prim;
1087 ops->wait_handle = ser_windows_wait_handle;
1089 serial_add_interface (ops);
1091 /* Next create the dummy serial driver used for terminals. We only
1092 provide the TTY-related methods. */
1094 ops = XMALLOC (struct serial_ops);
1095 memset (ops, 0, sizeof (struct serial_ops));
1097 ops->name = "terminal";
1098 ops->next = 0;
1100 ops->close = ser_console_close;
1101 ops->get_tty_state = ser_console_get_tty_state;
1102 ops->set_tty_state = ser_base_set_tty_state;
1103 ops->print_tty_state = ser_base_print_tty_state;
1104 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1105 ops->drain_output = ser_base_drain_output;
1106 ops->wait_handle = ser_console_wait_handle;
1107 ops->done_wait_handle = ser_console_done_wait_handle;
1109 serial_add_interface (ops);
1111 /* The pipe interface. */
1113 ops = XMALLOC (struct serial_ops);
1114 memset (ops, 0, sizeof (struct serial_ops));
1115 ops->name = "pipe";
1116 ops->next = 0;
1117 ops->open = pipe_windows_open;
1118 ops->close = pipe_windows_close;
1119 ops->readchar = ser_base_readchar;
1120 ops->write = ser_base_write;
1121 ops->flush_output = ser_base_flush_output;
1122 ops->flush_input = ser_base_flush_input;
1123 ops->send_break = ser_base_send_break;
1124 ops->go_raw = ser_base_raw;
1125 ops->get_tty_state = ser_base_get_tty_state;
1126 ops->set_tty_state = ser_base_set_tty_state;
1127 ops->print_tty_state = ser_base_print_tty_state;
1128 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1129 ops->setbaudrate = ser_base_setbaudrate;
1130 ops->setstopbits = ser_base_setstopbits;
1131 ops->drain_output = ser_base_drain_output;
1132 ops->async = ser_base_async;
1133 ops->read_prim = pipe_windows_read;
1134 ops->write_prim = pipe_windows_write;
1135 ops->wait_handle = pipe_wait_handle;
1137 serial_add_interface (ops);
1139 /* If WinSock works, register the TCP/UDP socket driver. */
1141 if (WSAStartup (MAKEWORD (1, 0), &wsa_data) != 0)
1142 /* WinSock is unavailable. */
1143 return;
1145 ops = XMALLOC (struct serial_ops);
1146 memset (ops, 0, sizeof (struct serial_ops));
1147 ops->name = "tcp";
1148 ops->next = 0;
1149 ops->open = net_windows_open;
1150 ops->close = net_windows_close;
1151 ops->readchar = ser_base_readchar;
1152 ops->write = ser_base_write;
1153 ops->flush_output = ser_base_flush_output;
1154 ops->flush_input = ser_base_flush_input;
1155 ops->send_break = ser_base_send_break;
1156 ops->go_raw = ser_base_raw;
1157 ops->get_tty_state = ser_base_get_tty_state;
1158 ops->set_tty_state = ser_base_set_tty_state;
1159 ops->print_tty_state = ser_base_print_tty_state;
1160 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
1161 ops->setbaudrate = ser_base_setbaudrate;
1162 ops->setstopbits = ser_base_setstopbits;
1163 ops->drain_output = ser_base_drain_output;
1164 ops->async = ser_base_async;
1165 ops->read_prim = net_read_prim;
1166 ops->write_prim = net_write_prim;
1167 ops->wait_handle = net_windows_wait_handle;
1168 ops->done_wait_handle = net_windows_done_wait_handle;
1169 serial_add_interface (ops);