]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* gdb/ser-mingw.c (net_windows_state): Add mutex.
authorMark Mitchell <mark@codesourcery.com>
Wed, 22 Mar 2006 01:22:28 +0000 (01:22 +0000)
committerMark Mitchell <mark@codesourcery.com>
Wed, 22 Mar 2006 01:22:28 +0000 (01:22 +0000)
(net_windows_select_thread): Grab lock around access to
read_event.
(net_windows_wait_handle): Do not reset the read_event.
(net_windows_open): Create a mutex.
(net_windows_read_prim): New function.
(_initialize_ser_windows): Use it.

ChangeLog.csl
gdb/ser-mingw.c

index 95a2ea8a1ee208f890477def3f4b41060765e6a1..77f90d9f71300aac4571ad6b6538bae7a842813e 100644 (file)
@@ -1,3 +1,13 @@
+2006-03-21  Mark Mitchell  <mark@codesourcery.com>
+
+       * gdb/ser-mingw.c (net_windows_state): Add mutex.
+       (net_windows_select_thread): Grab lock around access to
+       read_event.
+       (net_windows_wait_handle): Do not reset the read_event.
+       (net_windows_open): Create a mutex.
+       (net_windows_read_prim): New function.
+       (_initialize_ser_windows): Use it.
+
 2006-03-20  Mark Mitchell  <mark@codesourcery.com>
 
        * libiberty/pex-common.c (pex_run): Close the write end of the
index b5cd16eb26c2b1d44b3f176bd4e470d6e4707191..d170cec53d9a365f927687ad8b2aca692d241bb3 100644 (file)
@@ -784,6 +784,8 @@ pipe_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
 
 struct net_windows_state
 {
+  /* Every access to read_event is guarded by this mutex.  */
+  HANDLE mutex;
   HANDLE read_event;
   HANDLE except_event;
 
@@ -841,10 +843,11 @@ net_windows_select_thread (void *arg)
 
       /* Enumerate the internal network events, and reset the object that
         signalled us to catch the next event.  */
+      WaitForSingleObject (state->mutex, INFINITE);
       WSAEnumNetworkEvents (fd, state->sock_event, &events);
-
       if (events.lNetworkEvents & FD_READ)
        SetEvent (state->read_event);
+      ReleaseMutex (state->mutex);
 
       if (events.lNetworkEvents & FD_CLOSE)
        SetEvent (state->except_event);
@@ -856,7 +859,6 @@ net_windows_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
 {
   struct net_windows_state *state = scb->state;
 
-  ResetEvent (state->read_event);
   ResetEvent (state->except_event);
 
   SetEvent (state->start_select);
@@ -892,6 +894,9 @@ net_windows_open (struct serial *scb, const char *name)
   state->read_event = CreateEvent (0, FALSE, FALSE, 0);
   state->except_event = CreateEvent (0, FALSE, FALSE, 0);
 
+  /* Guard access to the read_event.  */
+  state->mutex = CreateMutex (NULL, FALSE, NULL);
+
   /* And finally start the select thread.  */
   CreateThread (NULL, 0, net_windows_select_thread, scb, 0, &threadId);
 
@@ -916,6 +921,27 @@ net_windows_close (struct serial *scb)
   net_close (scb);
 }
 
+static int
+net_windows_read_prim (struct serial *scb, size_t count)
+{
+  struct net_windows_state *state = scb->state;
+  int ret;
+
+  /* We're about to call recv.  If any bytes appear after this point,
+     we need to be told about them.  So, we must reset the read event.
+     However, if we reset the event, then read, we could read all the
+     bytes -- and leave the event signaled if the thread notices new
+     bytes arriving between the reset and the read.  Similarly, if we
+     read, then reset, we could miss new bytes arriving between the
+     read and the reset.  So, we must make the read and reset atomic.  */
+  WaitForSingleObject (state->mutex, INFINITE);
+  ResetEvent (state->read_event);
+  ret = net_read_prim (scb, count);
+  ReleaseMutex (state->mutex);
+
+  return ret;
+}
+
 void
 _initialize_ser_windows (void)
 {
@@ -1028,7 +1054,7 @@ _initialize_ser_windows (void)
   ops->setstopbits = ser_base_setstopbits;
   ops->drain_output = ser_base_drain_output;
   ops->async = ser_base_async;
-  ops->read_prim = net_read_prim;
+  ops->read_prim = net_windows_read_prim;
   ops->write_prim = net_write_prim;
   ops->wait_handle = net_windows_wait_handle;
   serial_add_interface (ops);