From bfcf6608012308f18740cf8b6d7d0e7e26c76022 Mon Sep 17 00:00:00 2001 From: Steven Tamm Date: Mon, 19 Jul 2004 06:38:14 +0000 Subject: [PATCH] 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 --- src/ChangeLog | 9 ++++ src/mac.c | 146 +++++++++++++++++++++++++++----------------------- src/sysdep.c | 4 -- 3 files changed, 89 insertions(+), 70 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index bc59ae9e2d7..0c8b389b65b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2004-07-18 YAMAMOTO Mitsuharu + + * 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 * mac.c (sys_select): Redo sys_select to use alarm-based diff --git a/src/mac.c b/src/mac.c index 0ccedfdea7c..9740b3bf3f4 100644 --- a/src/mac.c +++ b/src/mac.c @@ -2769,6 +2769,8 @@ and t is the same as `SECONDARY'. */) 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 @@ extern int noninteractive; 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 - { - 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) + return select (n, rfds, wfds, efds, timeout); + + if (wfds == NULL && efds == NULL) + { + 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; -#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; + 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 read (fds, buf, nbyte); + return 0; } - /* 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//, /usr/local/bin, diff --git a/src/sysdep.c b/src/sysdep.c index 5ede3d27208..d5236a3f88a 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -70,10 +70,6 @@ static int delete_exited_processes; #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 -- 2.39.2