* ser-mingw.c (free_pipe_state, pipe_wait_handle): Update
authorDaniel Jacobowitz <drow@false.org>
Tue, 10 Oct 2006 14:23:11 +0000 (14:23 +0000)
committerDaniel Jacobowitz <drow@false.org>
Tue, 10 Oct 2006 14:23:11 +0000 (14:23 +0000)
for changes to pipe_select_thread.
(pipe_done_wait_handle): New.
(_initialize_ser_windows): Reference it.

gdb/ChangeLog
gdb/ser-mingw.c

index c8605a9ea45ac6fd09cf012331e4d8a26c633f72..10993b3fae741439c748e0802b2f321eadaee06a 100644 (file)
@@ -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>
 
index 79e186b842d0ab812082e3f3e4d72f1b671cf3af..c0e124175e6051234f3dd4a50fc5a0b440673620 100644 (file)
@@ -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);