This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: Support Windows in event-loop.c


Daniel Jacobowitz wrote:

No idea.  I think in GDB is OK.  In that case it should probably be
encapsulated as "gdb_select".

Here is the revised patch. As per previous discussion, this version still has the limitation that it only works with consoles -- but it would be possible to use threads within gdb_select to extend it to work with a wider variety of handles. In any case, this patch provides useful functionality on Windows, and does not impose the Windows API on generic code.


OK to commit?

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
(916) 791-8304
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).
	
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.707
diff -c -5 -p -r1.707 Makefile.in
*** Makefile.in	18 Mar 2005 21:03:38 -0000	1.707
--- Makefile.in	25 Apr 2005 20:09:04 -0000
*************** environ.o: environ.c $(defs_h) $(environ
*** 1907,1917 ****
  eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
  	$(value_h) $(expression_h) $(target_h) $(frame_h) $(language_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)
  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)
  exceptions.o: exceptions.c $(defs_h) $(exceptions_h) $(breakpoint_h) \
  	$(target_h) $(inferior_h) $(annotate_h) $(ui_out_h) $(gdb_assert_h) \
--- 1910,1920 ----
  eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
  	$(value_h) $(expression_h) $(target_h) $(frame_h) $(language_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_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)
  exceptions.o: exceptions.c $(defs_h) $(exceptions_h) $(breakpoint_h) \
  	$(target_h) $(inferior_h) $(annotate_h) $(ui_out_h) $(gdb_assert_h) \
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	25 Apr 2005 20:20:34 -0000
***************
*** 34,43 ****
--- 34,44 ----
  #include <sys/types.h>
  #include "gdb_string.h"
  #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);
  
  /* Event for the GDB event system.  Events are queued by calling
*************** event_queue;
*** 131,140 ****
--- 132,146 ----
  #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;
  
*************** handle_file_event (int event_file_desc)
*** 723,732 ****
--- 729,806 ----
  	  break;
  	}
      }
  }
  
+ /* 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;
+ 
+   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.  */
+   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);
+     }
+   /* We never report any descriptors available for writing or with
+      exceptional conditions.  */ 
+   FD_ZERO (writefds);
+   FD_ZERO (exceptfds);
+ 
+   return 1;
+ #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. 
     If there are no events, this function will block in the 
     call to poll.
*************** gdb_wait_for_event (void)
*** 767,782 ****
    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_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)
  	{
  	  FD_ZERO (&gdb_notifier.ready_masks[0]);
--- 841,856 ----
    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 = 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)
  	{
  	  FD_ZERO (&gdb_notifier.ready_masks[0]);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]