Subject: Re: bug#16519: 24.3.50; gfile notifications not received in batch mode

From: Michael Albinus <[email-masked]>
Date: Thu, 30 Jan 2014 11:03:33 +0100

Eli Zaretskii <[email-masked]> writes:

>> > I don't know what it needs on w32 to get the file notification
>> > events. Is it sit-for?
>
> No, it seems to be read-event, see below.

`sit-for' calls `read-event', if `input-pending-p' returns nil. So it
shall be safe to call.

>> Finally, the following seems to work for all three file notification
>> libraries in interactive mode, and for inotify in batch mode:
>> 
>> (defmacro file-notify--wait-for-events (timeout until)
>>   "Wait for file notification events until form UNTIL is true.
>> TIMEOUT is the maximum time to wait for, in seconds."
>>   `(with-timeout (,timeout (ignore))
>>      (while (null ,until)
>>        (let (noninteractive)
>>         (sit-for 0.1 'nodisplay)))))
>> 
>> I am not able to test w32notify in batch mode. The following call from a
>> CMD terminal works fine for me:
>> 
>> C:\>"C:\Program Files\emacs\bin\runemacs.exe" -Q -l Y:\file-notify-tests.el -f ert
>
> How do you mean "works for me"?  The 02 test fails, doesn't it?  If I
> type "2" to the prompt, I get 1 unexpected failure and 1 skipped test.

All interactive cases work. In the noninteractive case, it works also
for inotify. For w32notify and gfilenotify it doesn't work yet, that's
why there is the expected result :fail.

I'm still working on the noninteractive gfilenotify case. The
integration of glib seems to be proper. According to some trace
messages I have added to dir_monitor_callback in gfilenotify.c, events
are received in test case `file-notify-test03-autorevert', but not in
`file-notify-test02-events'.

So it seems to be a problem read the events inside Emacs. The difference
between the two test cases is, that in the autorevert case there are
active timers. Maybe those timers trigger the event handling. I'll debug
further.

> I need this change to file-notify-tests.el to get it to work with w32
> in interactive mode (both -nw and GUI sessions work):
>
> === modified file 'test/automated/file-notify-tests.el'
> --- test/automated/file-notify-tests.el	2014-01-27 19:10:02 +0000
> +++ test/automated/file-notify-tests.el	2014-01-29 18:05:42 +0000
> @@ -188,7 +188,8 @@ TIMEOUT is the maximum time to wait for,
>    `(with-timeout (,timeout (ignore))
>       (while (null ,until)
>         (let (noninteractive)
> -	 (sit-for 0.1 'nodisplay)))))
> +	 (sit-for 0.1 'nodisplay)
> +	 (read-event)))))
>  
>  (ert-deftest file-notify-test02-events ()
>    "Check file creation/removal notifications."
>
> If we don't call read-event, the notifications are not read, since
> evidently the read_socket_hook isn't called.

Strange. Two days ago, I've installed the recent w32 snapshot (dated
20140119, IIRC) on an old Windows XP machine at work, plus the changed
file-notify-tests.el. All tests succeeded in the GUI case. I haven't
tried -nw, 'tho.

>> However, the batch-mode equivalent returns immediately without running
>> the test:
>> 
>> C:\>"C:\Program Files\emacs\bin\runemacs.exe" -batch -Q -l
>> Y:\file-notify-tests.el -f ert-run-tests-batch-and-exit
>> 
>> What do I miss?
>
> Don't run runemacs.exe, run emacs.exe instead.  I have no idea what
> will runemacs do in batch mode.

Ah, thanks. Will use for testing.

> Anyway, the read-event thing doesn't solve the -batch operation:
> notifications don't come in and Emacs is stuck until I type something
> on the keyboard.  I will need more debugging to understand what is
> going on.  One thing is clear: the way the notifications get to the
> event queue is different for every back-end, so naive assumptions,
> like just let it sit-for for a while, are usually wrong.

Again, at least for me it works with all 3 backends in interactive mode,
and it works for inotify in batch mode. And it works half way for
gfilenotify in batch mode for auto reverting files. And it works for
remote files, in both interactive and batch mode.

> Btw, why did you need to bind noninteractive to nil?

See the code of `sit-for'. When `noninteractive' is non-nil, it simply
calls `sleep-for'. That was proper in the past, but these days with
several events to arrive also in noninteractive mode, this should be
changed. Not something for the feature freeze time, that's why I have
masked it with binding noninteractive to nil in the test code. Maybe I
should add a respective comment.

A while ago, Stefan has proposed to add a new mechanism for handling
such events. Maybe this shall go there.

Best regards, Michael.