diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/Makefile.in | 2 | ||||
-rw-r--r-- | gdb/event-loop.c | 91 |
3 files changed, 95 insertions, 7 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e1e466e..c4a9b6d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,12 @@ +2005-04-25 Mark Mitchell <mark@codesourcery.com> + + * event-loop.c (gdb_assert.h): Include. + (<windows.h>): Include under Windows. + (<io.h>): Likeiwse. + (gdb_select): New function. + (gdb_wait_for_event): Use it. + * Makefile.in (event-loop.o): Depend on $(gdb_assert_h). + 2005-04-23 Mark Kettenis <kettenis@gnu.org> * sparc64-tdep.c: Include "dwarf2-frame.h". diff --git a/gdb/Makefile.in b/gdb/Makefile.in index e60a3e5..fdbb819 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1910,7 +1910,7 @@ eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \ $(f_lang_h) $(cp_abi_h) $(infcall_h) $(objc_lang_h) $(block_h) \ $(parser_defs_h) $(cp_support_h) event-loop.o: event-loop.c $(defs_h) $(event_loop_h) $(event_top_h) \ - $(gdb_string_h) $(exceptions_h) + $(gdb_string_h) $(exceptions_h) $(gdb_assert_h) event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \ $(terminal_h) $(event_loop_h) $(event_top_h) $(interps_h) \ $(exceptions_h) $(gdbcmd_h) $(readline_h) $(readline_history_h) diff --git a/gdb/event-loop.c b/gdb/event-loop.c index e4b09f4..1db32a8 100644 --- a/gdb/event-loop.c +++ b/gdb/event-loop.c @@ -36,6 +36,7 @@ #include <errno.h> #include <sys/time.h> #include "exceptions.h" +#include "gdb_assert.h" typedef struct gdb_event gdb_event; typedef void (event_handler_func) (int); @@ -133,6 +134,11 @@ event_queue; static unsigned char use_poll = USE_POLL; +#ifdef USE_WIN32API +#include <windows.h> +#include <io.h> +#endif + static struct { /* Ptr to head of file handler list. */ @@ -725,6 +731,79 @@ handle_file_event (int event_file_desc) } } +/* Wrapper for select. This function is not yet exported from this + file because it is not sufficiently general. For example, + ser-base.c uses select to check for socket activity, and this + function does not support sockets under Windows, so we do not want + to use gdb_select in ser-base.c. */ + +static int +gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ +#ifdef USE_WIN32API + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + HANDLE h; + DWORD event; + DWORD num_handles; + int fd; + int num_ready; + + num_handles = 0; + for (fd = 0; fd < n; ++fd) + { + /* EXCEPTFDS is silently ignored. GDB always sets GDB_EXCEPTION + when calling add_file_handler, but there is no natural analog + under Windows. */ + /* There is no support yet for WRITEFDS. At present, this isn't + used by GDB -- but we do not want to silently ignore WRITEFDS + if something starts using it. */ + gdb_assert (!FD_ISSET (fd, writefds)); + if (FD_ISSET (fd, readfds)) + handles[num_handles++] = (HANDLE) _get_osfhandle (fd); + } + event = WaitForMultipleObjects (num_handles, + handles, + FALSE, + timeout + ? (timeout->tv_sec * 1000 + timeout->tv_usec) + : INFINITE); + /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the + HANDLES included an abandoned mutex. Since GDB doesn't use + mutexes, that should never occur. */ + gdb_assert (!(WAIT_ABANDONED_0 <= event + && event < WAIT_ABANDONED_0 + num_handles)); + if (event == WAIT_FAILED) + return -1; + if (event == WAIT_TIMEOUT) + return 0; + /* Run through the READFDS, clearing bits corresponding to descriptors + for which input is unavailable. */ + num_ready = num_handlers; + h = handles[event - WAIT_OBJECT_0]; + for (fd = 0; fd < n; ++fd) + { + HANDLE fd_h = (HANDLE) _get_osfhandle (fd); + /* This handle might be ready, even though it wasn't the handle + returned by WaitForMultipleObjects. */ + if (FD_ISSET (fd, readfds) && fd_h != h + && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0) + { + FD_CLR (fd, readfds); + --num_ready; + } + } + /* We never report any descriptors available for writing or with + exceptional conditions. */ + FD_ZERO (writefds); + FD_ZERO (exceptfds); + + return num_ready; +#else + return select (n, readfds, writefds, exceptfds, timeout); +#endif +} + /* Called by gdb_do_one_event to wait for new events on the monitored file descriptors. Queue file events as they are detected by the poll. @@ -769,12 +848,12 @@ gdb_wait_for_event (void) gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0]; gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1]; gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2]; - num_found = select (gdb_notifier.num_fds, - &gdb_notifier.ready_masks[0], - &gdb_notifier.ready_masks[1], - &gdb_notifier.ready_masks[2], - gdb_notifier.timeout_valid - ? &gdb_notifier.select_timeout : NULL); + num_found = gdb_select (gdb_notifier.num_fds, + &gdb_notifier.ready_masks[0], + &gdb_notifier.ready_masks[1], + &gdb_notifier.ready_masks[2], + gdb_notifier.timeout_valid + ? &gdb_notifier.select_timeout : NULL); /* Clear the masks after an error from select. */ if (num_found == -1) |