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]

PATCH: Support Windows in event-loop.c


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;
  }
  
  


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