This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
PATCH: Support Windows in event-loop.c
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Wed, 20 Apr 2005 22:49:02 -0700
- Subject: PATCH: Support Windows in event-loop.c
- Reply-to: mark at codesourcery dot com
This is the last wpatch required to GDB proper to support execution on
Windows; the only other patches are relatively minor changes to
readline.
This patch adds support for Windows to event-loop.c. The key issue is
that "select" on Windows only works on sockets; it does not work on
general file descriptors. For that, one must use
WaitForMultipleObjects, and that requires converting file descriptors
(as used by read/write/open/close) to native HANDLEs.
OK to commit?
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
2005-03-28 Mark Mitchell <mark@codesourcery.com>
* gdb/event-loop.c (struct gdb_notifier): Add "handles" for Windows.
(create_file_handler): On Windows, update handles, rather than
check_masks and ready_masks.
(delete_file_handler): Likewise.
(gdb_wait_for_event): Use WaitForMultipleObjects, not select, on
Windows.
Index: event-loop.c
===================================================================
RCS file: /cvs/src/src/gdb/event-loop.c,v
retrieving revision 1.24
diff -c -5 -p -r1.24 event-loop.c
*** event-loop.c 12 Feb 2005 00:39:18 -0000 1.24
--- event-loop.c 21 Apr 2005 05:42:47 -0000
*************** event_queue;
*** 131,140 ****
--- 131,145 ----
#define USE_POLL 0
#endif /* HAVE_POLL */
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. */
file_handler *first_file_handler;
*************** static struct
*** 144,162 ****
/* Timeout in milliseconds for calls to poll(). */
int poll_timeout;
#endif
/* Masks to be used in the next call to select.
Bits are set in response to calls to create_file_handler. */
fd_set check_masks[3];
/* What file descriptors were found ready by select. */
fd_set ready_masks[3];
!
/* Number of file descriptors to monitor. (for poll) */
/* Number of valid bits (highest fd value + 1). (for select) */
int num_fds;
/* Time structure for calls to select(). */
struct timeval select_timeout;
--- 149,171 ----
/* Timeout in milliseconds for calls to poll(). */
int poll_timeout;
#endif
+ #ifdef USE_WIN32API
+ HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+ #else
/* Masks to be used in the next call to select.
Bits are set in response to calls to create_file_handler. */
fd_set check_masks[3];
/* What file descriptors were found ready by select. */
fd_set ready_masks[3];
! #endif
/* Number of file descriptors to monitor. (for poll) */
/* Number of valid bits (highest fd value + 1). (for select) */
+ /* Number of handles (for Windows). */
int num_fds;
/* Time structure for calls to select(). */
struct timeval select_timeout;
*************** create_file_handler (int fd, int mask, h
*** 522,531 ****
--- 531,544 ----
_("use_poll without HAVE_POLL"));
#endif /* HAVE_POLL */
}
else
{
+ #ifdef USE_WIN32API
+ gdb_notifier.handles[gdb_notifier.num_fds++]
+ = (HANDLE) _get_osfhandle (fd);
+ #else
if (mask & GDB_READABLE)
FD_SET (fd, &gdb_notifier.check_masks[0]);
else
FD_CLR (fd, &gdb_notifier.check_masks[0]);
*************** create_file_handler (int fd, int mask, h
*** 539,548 ****
--- 552,562 ----
else
FD_CLR (fd, &gdb_notifier.check_masks[2]);
if (gdb_notifier.num_fds <= fd)
gdb_notifier.num_fds = fd + 1;
+ #endif
}
}
file_ptr->proc = proc;
file_ptr->client_data = client_data;
*************** delete_file_handler (int fd)
*** 600,609 ****
--- 614,633 ----
_("use_poll without HAVE_POLL"));
#endif /* HAVE_POLL */
}
else
{
+ #ifdef USE_WIN32API
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ for (i = 0; i < gdb_notifier.num_fds; ++i)
+ if (gdb_notifier.handles[i] == h)
+ {
+ gdb_notifier.handles[i] =
+ gdb_notifier.handles[gdb_notifier.num_fds--];
+ break;
+ }
+ #else
if (file_ptr->mask & GDB_READABLE)
FD_CLR (fd, &gdb_notifier.check_masks[0]);
if (file_ptr->mask & GDB_WRITABLE)
FD_CLR (fd, &gdb_notifier.check_masks[1]);
if (file_ptr->mask & GDB_EXCEPTION)
*************** delete_file_handler (int fd)
*** 621,630 ****
--- 645,655 ----
|| FD_ISSET (i - 1, &gdb_notifier.check_masks[2]))
break;
}
gdb_notifier.num_fds = i;
}
+ #endif
}
/* Deactivate the file descriptor, by clearing its mask,
so that it will not fire again. */
*************** handle_file_event (int event_file_desc)
*** 735,745 ****
--- 760,774 ----
static int
gdb_wait_for_event (void)
{
file_handler *file_ptr;
gdb_event *file_event_ptr;
+ #ifdef USE_WIN32API
+ DWORD event = 0;
+ #else
int num_found = 0;
+ #endif
int i;
/* Make sure all output is done before getting another event. */
gdb_flush (gdb_stdout);
gdb_flush (gdb_stderr);
*************** gdb_wait_for_event (void)
*** 764,773 ****
--- 793,812 ----
_("use_poll without HAVE_POLL"));
#endif /* HAVE_POLL */
}
else
{
+ #ifdef USE_WIN32API
+ event
+ = WaitForMultipleObjects(gdb_notifier.num_fds,
+ gdb_notifier.handles,
+ FALSE,
+ gdb_notifier.timeout_valid
+ ? (gdb_notifier.select_timeout.tv_sec * 1000
+ + gdb_notifier.select_timeout.tv_usec)
+ : INFINITE);
+ #else
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_wait_for_event (void)
*** 784,793 ****
--- 823,833 ----
FD_ZERO (&gdb_notifier.ready_masks[2]);
/* Dont print anything is we got a signal, let gdb handle it. */
if (errno != EINTR)
perror_with_name (("select"));
}
+ #endif
}
/* Enqueue all detected file events. */
if (use_poll)
*************** gdb_wait_for_event (void)
*** 826,835 ****
--- 866,889 ----
_("use_poll without HAVE_POLL"));
#endif /* HAVE_POLL */
}
else
{
+ #ifdef USE_WIN32API
+ HANDLE h;
+
+ h = gdb_notifier.handles[event - WAIT_OBJECT_0];
+ file_ptr = gdb_notifier.first_file_handler;
+ while ((HANDLE) _get_osfhandle (file_ptr->fd) != h)
+ file_ptr = file_ptr->next_file;
+ if (file_ptr->ready_mask == 0)
+ {
+ file_event_ptr = create_file_event (file_ptr->fd);
+ async_queue_event (file_event_ptr, TAIL);
+ }
+ file_ptr->ready_mask = GDB_READABLE;
+ #else
for (file_ptr = gdb_notifier.first_file_handler;
(file_ptr != NULL) && (num_found > 0);
file_ptr = file_ptr->next_file)
{
int mask = 0;
*************** gdb_wait_for_event (void)
*** 854,863 ****
--- 908,918 ----
file_event_ptr = create_file_event (file_ptr->fd);
async_queue_event (file_event_ptr, TAIL);
}
file_ptr->ready_mask = mask;
}
+ #endif
}
return 0;
}