emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Mac OS X - Hang / C-g problem patch


From: Andrew Choi
Subject: Re: Mac OS X - Hang / C-g problem patch
Date: Wed, 04 Dec 2002 23:48:03 -0700
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3.50

Steven Tamm <address@hidden> writes:

> I just found some free time on my hands and got back around to working
> on the problem where in the carbon gui, C-g does not interrupt
> synchronous subprocesses.  This caused much consternation and after
> checking with some people at apple, there was no easy way.  The
> alternatives were to finish my Jaguar/MT UI patch (which I won't go
> into), or to make all blocking reads be in a separate thread.  [...]

Hi Steven,

I've checked that your patch works as advertised.

I've worked out a simpler solution that uses polling though.  The idea
is to patch `read' to call `select' to check for available input.  If
none is after one second, poll for a user-cancel and check for input
again and repeat.  Since I've used CheckEventQueueForUserCancel, the
command-period key is used instead of C-g.  We can probably change it to
C-g if we want.

The patch also handles the following cases: when Emacs is stuck in a
loop executing Lisp code and when it is stuck waiting for select instead
of read (e.g., sleep-for).

Performance will not be a problem except perhaps for the check in
`eval'.

Andrew.

Index: eval.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/eval.c,v
retrieving revision 1.197
diff -u -r1.197 eval.c
--- eval.c      21 Nov 2002 17:33:01 -0000      1.197
+++ eval.c      5 Dec 2002 05:22:48 -0000
@@ -27,6 +27,9 @@
 #include "keyboard.h"
 #include "dispextern.h"
 #include <setjmp.h>
+#ifdef MAC_OSX
+#include <signal.h>
+#endif
 
 /* This definition is duplicated in alloc.c and keyboard.c */
 /* Putting it in lisp.h makes cc bomb out! */
@@ -2154,6 +2157,12 @@
   if (backtrace.debug_on_exit)
     val = call_debugger (Fcons (Qexit, Fcons (val, Qnil)));
   backtrace_list = backtrace.next;
+
+#ifdef MAC_OSX
+  if (CheckEventQueueForUserCancel ())
+    kill (getpid (), SIGINT);
+#endif
+
   return val;
 }
 
Index: keyboard.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v
retrieving revision 1.716
diff -u -r1.716 keyboard.c
--- keyboard.c  22 Nov 2002 12:23:13 -0000      1.716
+++ keyboard.c  5 Dec 2002 05:23:00 -0000
@@ -10494,6 +10494,11 @@
   poll_suppress_count = 1;
   start_polling ();
 #endif
+
+#ifdef MAC_OSX
+  /* At least provide an escape route since C-g doesn't work.  */
+  signal (SIGINT, interrupt_signal);
+#endif
 }
 
 /* This type's only use is in syms_of_keyboard, to initialize the
Index: mac.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/mac.c,v
retrieving revision 1.10
diff -u -r1.10 mac.c
--- mac.c       18 Oct 2002 10:00:10 -0000      1.10
+++ mac.c       5 Dec 2002 05:23:01 -0000
@@ -2748,6 +2748,8 @@
 }
 
 #ifdef MAC_OSX
+#include <signal.h>
+
 #undef select
 
 extern int inhibit_window_system;
@@ -2768,9 +2770,60 @@
   if (!inhibit_window_system && rfds && FD_ISSET (0, rfds))
     return 1;
   else
-    return select (n, rfds, wfds, efds, timeout);
+    {
+      EMACS_TIME end_time, now;
+
+      EMACS_GET_TIME (end_time);
+      EMACS_ADD_TIME (end_time, end_time, *timeout);
+
+      do
+       {
+         int r;
+         EMACS_TIME one_second;
+
+         EMACS_SET_SECS (one_second, 1);
+         EMACS_SET_USECS (one_second, 0);
+         
+         if ((r = select (n, rfds, wfds, efds, &one_second)) > 0)
+           return r;
+         
+         if (CheckEventQueueForUserCancel ())
+           {
+             kill (getpid (), SIGINT);
+             return 0;
+           }
+
+         EMACS_GET_TIME (now);
+         EMACS_SUB_TIME (now, end_time, now);
+       }
+      while (!EMACS_TIME_NEG_P (now));
+
+      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;
+  
+  do 
+    {
+      FD_ZERO (&rfds);
+      FD_SET (fds, &rfds);
+
+      EMACS_SET_SECS (one_second, 1);
+      EMACS_SET_USECS (one_second, 0);
+    }  
+  while (sys_select (fds+1, &rfds, 0, 0, &one_second) == 0);
+
+  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
Index: sysdep.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/sysdep.c,v
retrieving revision 1.245
diff -u -r1.245 sysdep.c
--- sysdep.c    22 Nov 2002 12:22:43 -0000      1.245
+++ sysdep.c    5 Dec 2002 05:23:04 -0000
@@ -69,6 +69,10 @@
 #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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]