diff options
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/ser-mingw.c | 52 |
2 files changed, 46 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index c8605a9..10993b3 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2006-10-10 Daniel Jacobowitz <dan@codesourcery.com> + + * ser-mingw.c (free_pipe_state, pipe_wait_handle): Update + for changes to pipe_select_thread. + (pipe_done_wait_handle): New. + (_initialize_ser_windows): Reference it. + 2006-10-09 Jan Kratochvil <jan.kratochvil@redhat.com> Daniel Jacobowitz <dan@codesourcery.com> diff --git a/gdb/ser-mingw.c b/gdb/ser-mingw.c index 79e186b..c0e1241 100644 --- a/gdb/ser-mingw.c +++ b/gdb/ser-mingw.c @@ -658,16 +658,19 @@ 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); + { + SetEvent (ps->wait.exit_select); + + WaitForSingleObject (ps->wait.thread, INFINITE); - /* 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); + CloseHandle (ps->wait.start_select); + CloseHandle (ps->wait.stop_select); + CloseHandle (ps->wait.exit_select); + CloseHandle (ps->wait.have_stopped); + + CloseHandle (ps->wait.read_event); + CloseHandle (ps->wait.except_event); + } /* 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 @@ -812,9 +815,16 @@ pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) { DWORD threadId; - /* Create auto reset events to wake and terminate the select thread. */ + /* Create auto reset events to wake, stop, and exit the select + thread. */ ps->wait.start_select = CreateEvent (0, FALSE, FALSE, 0); ps->wait.stop_select = CreateEvent (0, FALSE, FALSE, 0); + ps->wait.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. */ + ps->wait.have_stopped = CreateEvent (0, TRUE, FALSE, 0); /* Create our own events to report read and exceptions separately. The exception event is currently never used. */ @@ -825,15 +835,30 @@ pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except) CreateThread (NULL, 0, pipe_select_thread, scb, 0, &threadId); } + *read = ps->wait.read_event; + *except = ps->wait.except_event; + + /* Start from a blank state. */ ResetEvent (ps->wait.read_event); ResetEvent (ps->wait.except_event); + ResetEvent (ps->wait.stop_select); + /* Start the select thread. */ SetEvent (ps->wait.start_select); - - *read = ps->wait.read_event; - *except = ps->wait.except_event; } +static void +pipe_done_wait_handle (struct serial *scb) +{ + struct pipe_state *ps = scb->state; + + /* Have we allocated our events yet? */ + if (ps->wait.read_event == INVALID_HANDLE_VALUE) + return; + + SetEvent (ps->wait.stop_select); + WaitForSingleObject (ps->wait.have_stopped, INFINITE); +} struct net_windows_state { @@ -1133,6 +1158,7 @@ _initialize_ser_windows (void) ops->read_prim = pipe_windows_read; ops->write_prim = pipe_windows_write; ops->wait_handle = pipe_wait_handle; + ops->done_wait_handle = pipe_done_wait_handle; serial_add_interface (ops); |