diff options
author | Mark Mitchell <mark@codesourcery.com> | 2006-03-22 01:22:28 +0000 |
---|---|---|
committer | Mark Mitchell <mark@codesourcery.com> | 2006-03-22 01:22:28 +0000 |
commit | c749c8e7df6f7a3e5f3575ffc62ea2619ce5bb2a (patch) | |
tree | bf478960faf9e485252bfebd570e92d30caf52f0 | |
parent | 43122d14a4b677927a540bd8d904961637caa9a2 (diff) | |
download | gdb-c749c8e7df6f7a3e5f3575ffc62ea2619ce5bb2a.tar.gz |
* 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.
-rw-r--r-- | ChangeLog.csl | 10 | ||||
-rw-r--r-- | gdb/ser-mingw.c | 32 |
2 files changed, 39 insertions, 3 deletions
diff --git a/ChangeLog.csl b/ChangeLog.csl index 95a2ea8a1ee..77f90d9f713 100644 --- a/ChangeLog.csl +++ b/ChangeLog.csl @@ -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 diff --git a/gdb/ser-mingw.c b/gdb/ser-mingw.c index b5cd16eb26c..d170cec53d9 100644 --- a/gdb/ser-mingw.c +++ b/gdb/ser-mingw.c @@ -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); |