* 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).
This commit is contained in:
Mark Mitchell 2005-04-25 21:45:56 +00:00
parent 6d633fd282
commit 011825f07d
3 changed files with 95 additions and 7 deletions

View File

@ -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".

View File

@ -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)

View File

@ -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)