From 9c099ca7fd30b424b3e2f183652de888cd9b30b7 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 28 Nov 2013 21:40:15 +0200 Subject: [PATCH] Fix bug #15933 with crashes in file-notify-tests on MS-Windows. Support w32 file notifications in batch mode. src/w32proc.c (sys_select): Don't wait on interrupt_handle if it is invalid (which happens in batch mode). If non-interactive, call handle_file_notifications to store file notification events in the input queue. src/w32notify.c (send_notifications): Handle FRAME_INITIAL frames as well. src/w32inevt.c (handle_file_notifications): Now external, not static. src/w32term.h (handle_file_notifications): Provide prototype. src/emacs.c (main) [HAVE_W32NOTIFY]: When non-interactive, call init_crit, since init_display, which does that otherwise, is not called. --- src/ChangeLog | 20 ++++++++++++++++++++ src/emacs.c | 4 ++++ src/w32inevt.c | 4 ++-- src/w32notify.c | 7 ++++++- src/w32proc.c | 34 ++++++++++++++++++++++++++++++---- src/w32term.h | 1 + 6 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 78dd236201..f3cbf4e1f1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,23 @@ +2013-11-28 Eli Zaretskii + + Support w32 file notifications in batch mode. + * w32proc.c (sys_select): Don't wait on interrupt_handle if it is + invalid (which happens in batch mode). If non-interactive, call + handle_file_notifications to store file notification events in the + input queue. (Bug#15933) + + * w32notify.c (send_notifications): Handle FRAME_INITIAL frames as + well. + + * w32inevt.c (handle_file_notifications): Now external, not + static. + + * w32term.h (handle_file_notifications): Provide prototype. + + * emacs.c (main) [HAVE_W32NOTIFY]: When non-interactive, call + init_crit, since init_display, which does that otherwise, is not + called. + 2013-11-27 Glenn Morris * Makefile.in ($(lispsource)/international/charprop.el): New. diff --git a/src/emacs.c b/src/emacs.c index 75082ecef7..159b0d5040 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -1517,6 +1517,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem init_keyboard (); /* This too must precede init_sys_modes. */ if (!noninteractive) init_display (); /* Determine terminal type. Calls init_sys_modes. */ +#if HAVE_W32NOTIFY + else + init_crit (); /* w32notify.c needs this in batch mode. */ +#endif /* HAVE_W32NOTIFY */ init_xdisp (); #ifdef HAVE_WINDOW_SYSTEM init_fringe (); diff --git a/src/w32inevt.c b/src/w32inevt.c index dc587de118..a157cb5c1d 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -608,7 +608,7 @@ maybe_generate_resize_event (void) } #if HAVE_W32NOTIFY -static int +int handle_file_notifications (struct input_event *hold_quit) { BYTE *p = file_notifications; @@ -676,7 +676,7 @@ handle_file_notifications (struct input_event *hold_quit) return nevents; } #else /* !HAVE_W32NOTIFY */ -static int +int handle_file_notifications (struct input_event *hold_quit) { return 0; diff --git a/src/w32notify.c b/src/w32notify.c index 1f2ef83b2f..373e20e8e9 100644 --- a/src/w32notify.c +++ b/src/w32notify.c @@ -163,7 +163,12 @@ send_notifications (BYTE *info, DWORD info_size, void *desc, && PostThreadMessage (dwMainThreadId, WM_EMACS_FILENOTIFY, 0, 0)) || (FRAME_W32_P (f) && PostMessage (FRAME_W32_WINDOW (f), - WM_EMACS_FILENOTIFY, 0, 0))) + WM_EMACS_FILENOTIFY, 0, 0)) + /* When we are running in batch mode, there's no one to + send a message, so we just signal the data is + available and hope sys_select will be called soon and + will read the data. */ + || (FRAME_INITIAL_P (f) && noninteractive)) notification_buffer_in_use = 1; done = 1; } diff --git a/src/w32proc.c b/src/w32proc.c index ea16f26a0e..3e0081cd80 100644 --- a/src/w32proc.c +++ b/src/w32proc.c @@ -1960,12 +1960,17 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, FD_ZERO (rfds); nr = 0; - /* Always wait on interrupt_handle, to detect C-g (quit). */ - wait_hnd[0] = interrupt_handle; - fdindex[0] = -1; + /* If interrupt_handle is available and valid, always wait on it, to + detect C-g (quit). */ + nh = 0; + if (interrupt_handle && interrupt_handle != INVALID_HANDLE_VALUE) + { + wait_hnd[0] = interrupt_handle; + fdindex[0] = -1; + nh++; + } /* Build a list of pipe handles to wait on. */ - nh = 1; for (i = 0; i < nfds; i++) if (FD_ISSET (i, &orfds)) { @@ -1986,6 +1991,11 @@ sys_select (int nfds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds, FD_SET (i, rfds); return 1; } + else if (noninteractive) + { + if (handle_file_notifications (NULL)) + return 1; + } } else { @@ -2086,6 +2096,11 @@ count_children: { if (timeout) Sleep (timeout_ms); + if (noninteractive) + { + if (handle_file_notifications (NULL)) + return 1; + } return 0; } @@ -2112,6 +2127,11 @@ count_children: } else if (active == WAIT_TIMEOUT) { + if (noninteractive) + { + if (handle_file_notifications (NULL)) + return 1; + } return 0; } else if (active >= WAIT_OBJECT_0 @@ -2218,6 +2238,12 @@ count_children: break; } while (active < nh + nc); + if (noninteractive) + { + if (handle_file_notifications (NULL)) + nr++; + } + /* If no input has arrived and timeout hasn't expired, wait again. */ if (nr == 0) { diff --git a/src/w32term.h b/src/w32term.h index b3c0cf56c7..6825e3cd54 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -680,6 +680,7 @@ extern DWORD notifications_size; extern void *notifications_desc; extern Lisp_Object w32_get_watch_object (void *); extern Lisp_Object lispy_file_action (DWORD); +extern int handle_file_notifications (struct input_event *); extern void w32_initialize_display_info (Lisp_Object); extern void initialize_w32_display (struct terminal *, int *, int *); -- 2.20.1