changeset 56479:45d805d79d29

mac.c (sys_select): Block input around call to ReceiveNextEvent to prevent breakage. Correctly handle blocking on event queue only by calling ReceiveNextEvent instead of select (since GUI events aren't on an fd). (sys_read): Remove function sysdep.c: Remove redefine of read to sys_read if HAVE_CARBON
author Steven Tamm <steventamm@mac.com>
date Mon, 19 Jul 2004 06:38:14 +0000
parents 574f29ec464b
children 5e87c40cea58
files src/ChangeLog src/mac.c src/sysdep.c
diffstat 3 files changed, 92 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Jul 19 05:20:01 2004 +0000
+++ b/src/ChangeLog	Mon Jul 19 06:38:14 2004 +0000
@@ -1,3 +1,12 @@
+2004-07-18  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
+
+	* mac.c (sys_select): Block input around call to
+	ReceiveNextEvent to prevent breakage.  Correctly handle
+	blocking on event queue only by calling ReceiveNextEvent
+	instead of select (since GUI events aren't on an fd).
+	(sys_read): Remove function
+	* sysdep.c: Remove redefine of read to sys_read if HAVE_CARBON
+
 2004-07-18  YAMAMOTO Mitsuharu  <mituharu@math.s.chiba-u.ac.jp>
 
 	* mac.c (sys_select): Redo sys_select to use alarm-based
--- a/src/mac.c	Mon Jul 19 05:20:01 2004 +0000
+++ b/src/mac.c	Mon Jul 19 06:38:14 2004 +0000
@@ -2769,6 +2769,8 @@
 extern int inhibit_window_system;
 extern int noninteractive;
 
+#include "blockinput.h"
+
 /* When Emacs is started from the Finder, SELECT always immediately
    returns as if input is present when file descriptor 0 is polled for
    input.  Strangely, when Emacs is run as a GUI application from the
@@ -2776,88 +2778,100 @@
    the system call SELECT corrects this discrepancy.  */
 int
 sys_select (n, rfds, wfds, efds, timeout)
-  int n;
-  SELECT_TYPE *rfds;
-  SELECT_TYPE *wfds;
-  SELECT_TYPE *efds;
-  struct timeval *timeout;
+     int n;
+     SELECT_TYPE *rfds;
+     SELECT_TYPE *wfds;
+     SELECT_TYPE *efds;
+     struct timeval *timeout;
 {
+  OSErr err;
+  EMACS_TIME end_time, now, remaining_time;
+ 
   if (inhibit_window_system || noninteractive
       || rfds == NULL || !FD_ISSET (0, rfds))
-    return select(n, rfds, wfds, efds, timeout);    
-  else
+    return select (n, rfds, wfds, efds, timeout);
+  
+  if (wfds == NULL && efds == NULL)
     {
-      EMACS_TIME end_time, now;
-
-      EMACS_GET_TIME (end_time);
-      if (timeout)
-	EMACS_ADD_TIME (end_time, end_time, *timeout);
-
-      do
-	{
-	  EMACS_TIME select_timeout;
-	  SELECT_TYPE orfds = *rfds;
-	  int r;
-	  OSErr err;
-
-	  EMACS_SET_SECS (select_timeout, 0);
-	  EMACS_SET_USECS (select_timeout, 100);
-	  
-	  if (timeout && EMACS_TIME_LT (*timeout, select_timeout))
-	    select_timeout = *timeout;
-	  
-	  r = select (n, &orfds, wfds, efds, &select_timeout);
-	  err = ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, NULL);
-	  if (r > 0)
-            {
-              *rfds = orfds;
-	      if (err == noErr)
-		{
-		  FD_SET (0, rfds);
-		  r++;
-		}
-              return r;
-            }
-	  else if (err == noErr)
+      int i;
+
+      for (i = 1; i < n; i++)
+	if (FD_ISSET (i, rfds))
+	  break;
+      if (i == n)
+  	{
+	  EventTimeout timeout_sec =
+	    (timeout
+	     ? (EMACS_SECS (*timeout) * kEventDurationSecond
+		+ EMACS_USECS (*timeout) * kEventDurationMicrosecond)
+	     : kEventDurationForever);
+
+	  BLOCK_INPUT;
+	  err = ReceiveNextEvent (0, NULL, timeout_sec,
+				  kEventLeaveInQueue, NULL);
+	  UNBLOCK_INPUT;
+	  if (err == noErr)
 	    {
 	      FD_ZERO (rfds);
 	      FD_SET (0, rfds);
 	      return 1;
 	    }
-	  
-	  EMACS_GET_TIME (now);
-	  EMACS_SUB_TIME (now, end_time, now);
+	  else
+	    return 0;
 	}
-      while (!timeout || !EMACS_TIME_NEG_P (now));
-
-      return 0;
+    }
+
+  if (timeout)
+    {
+      remaining_time = *timeout;
+      EMACS_GET_TIME (now);
+      EMACS_ADD_TIME (end_time, now, remaining_time);
     }
+  FD_CLR (0, rfds);
+  do
+    {
+      EMACS_TIME select_timeout;
+      SELECT_TYPE orfds = *rfds;
+      int r;
+
+      EMACS_SET_SECS_USECS (select_timeout, 0, 20000);
+
+      if (timeout && EMACS_TIME_LT (remaining_time, select_timeout))
+	select_timeout = remaining_time;
+
+      r = select (n, &orfds, wfds, efds, &select_timeout);
+      BLOCK_INPUT;
+      err = ReceiveNextEvent (0, NULL, kEventDurationNoWait,
+			      kEventLeaveInQueue, NULL);
+      UNBLOCK_INPUT;
+      if (r > 0)
+	{
+	  *rfds = orfds;
+	  if (err == noErr)
+	    {
+	      FD_SET (0, rfds);
+	      r++;
+	    }
+	  return r;
+	}
+      else if (err == noErr)
+	{
+	  FD_ZERO (rfds);
+	  FD_SET (0, rfds);
+	  return 1;
+	}
+
+      if (timeout)
+	{
+	  EMACS_GET_TIME (now);
+	  EMACS_SUB_TIME (remaining_time, end_time, now);
+	}
+    }
+  while (!timeout || EMACS_TIME_LT (now, end_time));
+
+  return 0;
 }
 
-#undef read
-int sys_read (fds, buf, nbyte)
-     int fds;
-     char *buf;
-     unsigned int nbyte;
-{
-  SELECT_TYPE rfds;
-  EMACS_TIME one_second;
-  int r;
-
-  /* Use select to block on IO while still checking for quit_char */
-  if (!inhibit_window_system && !noninteractive &&
-      ! (fcntl(fds, F_GETFL, 0) & O_NONBLOCK))
-    {
-      FD_ZERO (&rfds);
-      FD_SET (fds, &rfds);
-      if (sys_select (fds+1, &rfds, 0, 0, NULL) < 0)
-	return -1;
-    }
-
-  return read (fds, buf, nbyte);
-}
-
-
 /* Set up environment variables so that Emacs can correctly find its
    support files when packaged as an application bundle.  Directories
    placed in /usr/local/share/emacs/<emacs-version>/, /usr/local/bin,
--- a/src/sysdep.c	Mon Jul 19 05:20:01 2004 +0000
+++ b/src/sysdep.c	Mon Jul 19 06:38:14 2004 +0000
@@ -70,10 +70,6 @@
 #endif
 #endif /* not WINDOWSNT */
 
-#ifdef HAVE_CARBON
-#define read sys_read
-#endif
-
 /* Does anyone other than VMS need this? */
 #ifndef fwrite
 #define sys_fwrite fwrite