# HG changeset patch # User Steven Tamm # Date 1090219094 0 # Node ID 45d805d79d291b1f5a31b9a53b3525b656271335 # Parent 574f29ec464b0ce56388621928f2aafdf373730f 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 diff -r 574f29ec464b -r 45d805d79d29 src/ChangeLog --- 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 + + * 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 -r 574f29ec464b -r 45d805d79d29 src/mac.c --- 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//, /usr/local/bin, diff -r 574f29ec464b -r 45d805d79d29 src/sysdep.c --- 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