unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#13400: 23.4; overlapping process filter calls
@ 2013-01-10 10:11 Hendrik Tews
  2019-07-27  3:38 ` Noam Postavsky
  0 siblings, 1 reply; 15+ messages in thread
From: Hendrik Tews @ 2013-01-10 10:11 UTC (permalink / raw)
  To: 13400

Hi,

because Stefan Monnier asked for it
(http://lists.inf.ed.ac.uk/pipermail/proofgeneral-devel/2013/000296.html):

When a process filter does I/O (eg, process-send-string), it
might happen, that the same filter is called again for the same
process, while the first instance blocks. To reproduce, load the
code below and do M-x double-filter.

The problem is real with Coq Proof General and Prooftree. There,
Prooftree is driven from a process filter in Proof General. With
cold disk caches, it takes about 1 sec to start Prooftree (at
least on my laptops). Coq and Proof General easily fill the pipe
in that time, so that the process filter blocks inside
process-send-string. Meanwhile Coq continues to produce output
and the process filter is called again while the previous call
has not finished.

The more I think about it, I believe this is a feature. 

However, the documentation is sometimes wrong and could be
clearer about this feature:

- Section "37.9 Receiving Output from Processes" does not list
  process-send-string. How about other blocking I/O functions?

- Same in "37.9.2. Process Filter Functions"

- Same in "37.4 Creating an Asynchronous Process" ,
  process-send-string is neither waiting for input not time
  delay.

- "37.7 Sending Input to Processes" says that filters can run
  inside process-send-string, but it could be clearer about the
  point that this can also happen inside the same filter for the
  same process.

- "37.9.2 Process Filter Functions" ignores the problem
  completely. There should be a paragraph clearly stating this
  problem. Further, it would be nice, if the filter function
  example could be extended to correctly deal with this problem.


To make it easier in the future to deal with this problem, I
suggest to add a process specific flag
``process-no-concurrent-filters''. When this flag is t for a
process, Emacs accepts output from this process inside a filter
but buffers it without calling the filter. The call to the filter
is delayed until a point where no filter for this process is
running. An error is signaled, if the buffered output exceeds a
certain size.


===========================================================================
(defun double-filter ()
  (interactive)
  (setq df-process (start-process "tee" nil "/bin/cat"))
  (set-process-filter df-process 'df-filter)
  (set-process-sentinel df-process 'df-sentinel)
  (set-process-query-on-exit-flag df-process nil)
  (setq df-buf (get-buffer-create "xxxx"))
  (process-send-string df-process "1\n"))

(setq df-filter-lock nil)
(setq df-error nil)

(defun df-filter (p str)
  (unless df-error
    (with-current-buffer df-buf
      (insert (format "filter received %d bytes lock %s\n"
		      (length str) df-filter-lock)))
    (when df-filter-lock
      (setq df-error t)
      (error "recursive filter"))
    (setq df-filter-lock t)
    (setq long (make-string 4096 65))
    (process-send-string df-process long)
    (process-send-string df-process long)
    (process-send-string df-process long)
    (process-send-string df-process long)
    (process-send-string df-process long)
    (process-send-string df-process long)
    (process-send-string df-process long)
    (process-send-string df-process long)
    (setq df-filter-lock nil)))

(defun df-sentinel (p event)
  (setq df-error t)
  (with-current-buffer df-bug
    (insert "process died\n")))
==============================================================================
 



In GNU Emacs 23.4.1 (i486-pc-linux-gnu, GTK+ Version 2.24.10)
 of 2012-09-09 on murphy, modified by Debian
Windowing system distributor `The X.Org Foundation', version 11.0.11204000
configured using `configure  '--build' 'i486-linux-gnu' '--build' 'i486-linux-gnu' '--prefix=/usr' '--sharedstatedir=/var/lib' '--libexecdir=/usr/lib' '--localstatedir=/var/lib' '--infodir=/usr/share/info' '--mandir=/usr/share/man' '--with-pop=yes' '--enable-locallisppath=/etc/emacs23:/etc/emacs:/usr/local/share/emacs/23.4/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/23.4/site-lisp:/usr/share/emacs/site-lisp' '--with-crt-dir=/usr/lib/i386-linux-gnu' '--with-x=yes' '--with-x-toolkit=gtk' '--with-toolkit-scroll-bars' 'build_alias=i486-linux-gnu' 'CFLAGS=-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wall -DDEBIAN -O2' 'CPPFLAGS=-D_FORTIFY_SOURCE=2''

Important settings:
  value of $LC_ALL: nil
  value of $LC_COLLATE: nil
  value of $LC_CTYPE: nil
  value of $LC_MESSAGES: nil
  value of $LC_MONETARY: nil
  value of $LC_NUMERIC: nil
  value of $LC_TIME: nil
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: nil
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t

Major mode: Emacs-Lisp

Minor modes in effect:
  show-paren-mode: t
  msb-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t






^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2013-01-10 10:11 bug#13400: 23.4; overlapping process filter calls Hendrik Tews
@ 2019-07-27  3:38 ` Noam Postavsky
  2019-07-27  8:24   ` Eli Zaretskii
  2019-08-05 22:37   ` Hendrik Tews
  0 siblings, 2 replies; 15+ messages in thread
From: Noam Postavsky @ 2019-07-27  3:38 UTC (permalink / raw)
  To: Hendrik Tews; +Cc: 13400, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 1486 bytes --]

Hendrik Tews <hendrik@askra.de> writes:

> because Stefan Monnier asked for it
> (http://lists.inf.ed.ac.uk/pipermail/proofgeneral-devel/2013/000296.html)

[Note: meanwhile the section number has changed to 38 instead of 37.]

> - Section "37.9 Receiving Output from Processes" does not list
>   process-send-string. How about other blocking I/O functions?

In the attached patch, I've added a mention/xref for functions which send
data to processes.

> - Same in "37.9.2. Process Filter Functions"

This section is repeated twice (I addressed the second instance below).

> - Same in "37.4 Creating an Asynchronous Process" ,
>   process-send-string is neither waiting for input not time
>   delay.

I don't see any mention of process-send-string in that section, nor how
it's relevant to the rest of this report.

> - "37.7 Sending Input to Processes" says that filters can run
>   inside process-send-string, but it could be clearer about the
>   point that this can also happen inside the same filter for the
>   same process.

I'm not really convinced that is necessary.

> - "37.9.2 Process Filter Functions" ignores the problem
>   completely. There should be a paragraph clearly stating this
>   problem. Further, it would be nice, if the filter function
>   example could be extended to correctly deal with this problem.

I added a mention of the possibility of recursion.  I'm not sure about
making an example (specifically, what is the best way to deal with this
problem?).


[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 2100 bytes --]

From 022fb3f287d4fd351078f2b134d187ff584b380c Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Fri, 26 Jul 2019 23:20:37 -0400
Subject: [PATCH] Note that process filter can be called recursively
 (Bug#13400)

* doc/lispref/processes.texi (Output from Processes): Note that
functions which send data may also trigger reading from processes.
(Filter Functions): Note that filter functions may be called
recursively.
---
 doc/lispref/processes.texi | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index a93f4db428..208005772e 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -1416,9 +1416,10 @@ Output from Processes
 
   Output from a subprocess can arrive only while Emacs is waiting: when
 reading terminal input (see the function @code{waiting-for-user-input-p}),
-in @code{sit-for} and @code{sleep-for} (@pxref{Waiting}), and in
-@code{accept-process-output} (@pxref{Accepting Output}).  This
-minimizes the problem of timing errors that usually plague parallel
+in @code{sit-for} and @code{sleep-for} (@pxref{Waiting}), in
+@code{accept-process-output} (@pxref{Accepting Output}), and in
+functions which send data to processes (pxref{Input to Processes}).
+This minimizes the problem of timing errors that usually plague parallel
 programming.  For example, you can safely create a process and only
 then specify its buffer or filter function; no output can arrive
 before you finish, if the code in between does not call any primitive
@@ -1683,6 +1684,10 @@ Filter Functions
 or more batches of output; one way to do this is to insert the
 received text into a temporary buffer, which can then be searched.
 
+Note that if the filter calls a function which can wait for process
+output (pxref{Output from Processes}), the filter may be called
+recursively.
+
 @defun set-process-filter process filter
 This function gives @var{process} the filter function @var{filter}.  If
 @var{filter} is @code{nil}, it gives the process the default filter,
-- 
2.11.0


[-- Attachment #3: Type: text/plain, Size: 1366 bytes --]


> To make it easier in the future to deal with this problem, I
> suggest to add a process specific flag
> ``process-no-concurrent-filters''. When this flag is t for a
> process, Emacs accepts output from this process inside a filter
> but buffers it without calling the filter. The call to the filter
> is delayed until a point where no filter for this process is
> running. An error is signaled, if the buffered output exceeds a
> certain size.

I thought of just making a wrapper in Lisp instead, this saves the need
to complicate the process C code with yet another flag; it's already
tricky enough as it is.

;;; -*- lexical-binding: t -*-

(defun make-buffered-filter (filter)
  (let ((filtering nil)
        (buffered nil)
        (process nil))
    (lambda (proc str)
      (if process
          (unless (eq process proc)
            (error "Buffered filter used in different processes: %S, %S"
                   proc process))
        (setq process proc))
      (push str buffered)
      (unless filtering
        (setq filtering t)
        (unwind-protect
            (while buffered
              (setq str (apply #'concat (nreverse buffered)))
              (setq buffered nil)
              (funcall filter proc str))
          (setq filtering nil))))))

;; Can be used like
(set-process-filter my-process (make-buffered-filter #'my-filter-function))


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-07-27  3:38 ` Noam Postavsky
@ 2019-07-27  8:24   ` Eli Zaretskii
  2019-08-04  0:02     ` Noam Postavsky
  2019-08-05 22:37   ` Hendrik Tews
  1 sibling, 1 reply; 15+ messages in thread
From: Eli Zaretskii @ 2019-07-27  8:24 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: hendrik, 13400, monnier

> From: Noam Postavsky <npostavs@gmail.com>
> Date: Fri, 26 Jul 2019 23:38:46 -0400
> Cc: 13400@debbugs.gnu.org, Stefan Monnier <monnier@iro.umontreal.ca>
> 
> > - Section "37.9 Receiving Output from Processes" does not list
> >   process-send-string. How about other blocking I/O functions?
> 
> In the attached patch, I've added a mention/xref for functions which send
> data to processes.
> 
> > - Same in "37.9.2. Process Filter Functions"
> 
> This section is repeated twice (I addressed the second instance below).
> 
> > - Same in "37.4 Creating an Asynchronous Process" ,
> >   process-send-string is neither waiting for input not time
> >   delay.
> 
> I don't see any mention of process-send-string in that section, nor how
> it's relevant to the rest of this report.
> 
> > - "37.7 Sending Input to Processes" says that filters can run
> >   inside process-send-string, but it could be clearer about the
> >   point that this can also happen inside the same filter for the
> >   same process.
> 
> I'm not really convinced that is necessary.
> 
> > - "37.9.2 Process Filter Functions" ignores the problem
> >   completely. There should be a paragraph clearly stating this
> >   problem. Further, it would be nice, if the filter function
> >   example could be extended to correctly deal with this problem.
> 
> I added a mention of the possibility of recursion.  I'm not sure about
> making an example (specifically, what is the best way to deal with this
> problem?).

I agree with Noam's decisions, and think that his patch is fine.

Thanks.





^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-07-27  8:24   ` Eli Zaretskii
@ 2019-08-04  0:02     ` Noam Postavsky
  2019-08-04 16:29       ` Eli Zaretskii
  2019-08-05 18:31       ` Stefan Monnier
  0 siblings, 2 replies; 15+ messages in thread
From: Noam Postavsky @ 2019-08-04  0:02 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: hendrik, 13400, monnier

Eli Zaretskii <eliz@gnu.org> writes:

>> > - "37.9.2 Process Filter Functions" ignores the problem
>> >   completely. There should be a paragraph clearly stating this
>> >   problem. Further, it would be nice, if the filter function
>> >   example could be extended to correctly deal with this problem.
>> 
>> I added a mention of the possibility of recursion.  I'm not sure about
>> making an example (specifically, what is the best way to deal with this
>> problem?).
>
> I agree with Noam's decisions, and think that his patch is fine.
>
> Thanks.

Any thoughts about make-buffered-filter?  Leave it up to callers to
write their own most situation-appropriate version of it?  Add it as an
example to the manual?  Add it to Emacs?





^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-04  0:02     ` Noam Postavsky
@ 2019-08-04 16:29       ` Eli Zaretskii
  2019-08-05 18:31       ` Stefan Monnier
  1 sibling, 0 replies; 15+ messages in thread
From: Eli Zaretskii @ 2019-08-04 16:29 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: hendrik, 13400, monnier

> From: Noam Postavsky <npostavs@gmail.com>
> Cc: hendrik@askra.de,  13400@debbugs.gnu.org,  monnier@iro.umontreal.ca
> Date: Sat, 03 Aug 2019 20:02:40 -0400
> 
> Any thoughts about make-buffered-filter?  Leave it up to callers to
> write their own most situation-appropriate version of it?  Add it as an
> example to the manual?  Add it to Emacs?

I'd go with the example in the manual alternative.





^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-04  0:02     ` Noam Postavsky
  2019-08-04 16:29       ` Eli Zaretskii
@ 2019-08-05 18:31       ` Stefan Monnier
  2019-08-08  3:37         ` Noam Postavsky
  1 sibling, 1 reply; 15+ messages in thread
From: Stefan Monnier @ 2019-08-05 18:31 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: 13400, hendrik

>>> > - "37.9.2 Process Filter Functions" ignores the problem
>>> >   completely. There should be a paragraph clearly stating this
>>> >   problem. Further, it would be nice, if the filter function
>>> >   example could be extended to correctly deal with this problem.
>>> 
>>> I added a mention of the possibility of recursion.  I'm not sure about
>>> making an example (specifically, what is the best way to deal with this
>>> problem?).
>>
>> I agree with Noam's decisions, and think that his patch is fine.
>>
>> Thanks.
>
> Any thoughts about make-buffered-filter?  Leave it up to callers to
> write their own most situation-appropriate version of it?  Add it as an
> example to the manual?  Add it to Emacs?

I'm pretty sure that while there might be use-cases for recursive
invocation of filters, this is a very exceptional situation and the
average programmer will not expect it and would be stumped if/when
it happens.

So the default should be to prevent it, with maybe some way to override
it to cater to the exceptional case where recursive invocation
is to be allowed.

I think we could do that by setting a property on process object during
filter invocation to postpone further filter invocations, and then the
process filter could locally unset this property if it wants to allow
recursive invocations.


        Stefan






^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-07-27  3:38 ` Noam Postavsky
  2019-07-27  8:24   ` Eli Zaretskii
@ 2019-08-05 22:37   ` Hendrik Tews
  2019-08-06  7:40     ` Stefan Monnier
  2019-08-08  1:15     ` Noam Postavsky
  1 sibling, 2 replies; 15+ messages in thread
From: Hendrik Tews @ 2019-08-05 22:37 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: 13400, Stefan Monnier

Noam,

thanks for addressing this quite old bug report. I do have some
comments:

Noam Postavsky <npostavs@gmail.com> writes:

> Hendrik Tews <hendrik@askra.de> writes:
>
>> because Stefan Monnier asked for it
>> (http://lists.inf.ed.ac.uk/pipermail/proofgeneral-devel/2013/000296.html)
>
> [Note: meanwhile the section number has changed to 38 instead of 37.]
>
>> - Section "37.9 Receiving Output from Processes" does not list
>>   process-send-string. How about other blocking I/O functions?
>
> In the attached patch, I've added a mention/xref for functions which send
> data to processes.

How about other blocking I/O functions? When output is accepted
inside process-send-string, then it probably is in all
potentially blocking I/O functions? The list of functions in 38.9
after "Output from a subprocess can arrive only" should be
complete. If the programmer cannot rely on the documentation to
be complete here, he or she has no other choice than to assume
that output can arrive anywhere and he/she _is_ plagued with the
usual parallel programming problems.

Therefore, please make a careful investigation to ensure that the
list of functions in which output can arrive is _really_ complete
in the documentation.

>> - Same in "37.9.2. Process Filter Functions"
>
> This section is repeated twice (I addressed the second instance below).

I mentioned this section twice, because there are _two_
documentation problems. I really believe you should address both
and not just one. The first problem in 38.9.2 is the same as
above: The list of functions after "The filter function can only
be called" is far from complete.

The second problem is that it does not document the possibility
of recursive filter calls.

>> - Same in "37.4 Creating an Asynchronous Process" ,
>>   process-send-string is neither waiting for input not time
>>   delay.
>
> I don't see any mention of process-send-string in that section, nor how
> it's relevant to the rest of this report.

Come on, please read that section carefully. "Emacs accepts data
from the process only while waiting for input or for a time
delay" in there implies that Emacs is _not_ accepting data during
process-send-string, because, as I wrote, 

>>   process-send-string is neither waiting for input no[r] time
>>   delay.

Therefore, this section implies that Emacs is _not_ accepting
data during process-send-string. If it does, it is a bug.

>> - "37.7 Sending Input to Processes" says that filters can run
>>   inside process-send-string, but it could be clearer about the
>>   point that this can also happen inside the same filter for the
>>   same process.
>
> I'm not really convinced that is necessary.

It is about a few words making the documentation more precise,
potentially saving somebody a painful debugging session of
several hours - similar to what I went through in 2013. Back
then, I was lucky because clearing the disk caches was enough to
reproduce the problem. Today with SSD's it is probably much
harder...

Adding to the original bug report, I would suggest to restructure
the documentation, such that there is only one section
documenting all the functions in which process output could
arrive and such that all the other sections only refer to that
section. It should really not be the case that different sections
make different and sometimes inconsistent statements about the
same feature.

Hendrik





^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-05 22:37   ` Hendrik Tews
@ 2019-08-06  7:40     ` Stefan Monnier
  2019-08-08  1:15     ` Noam Postavsky
  1 sibling, 0 replies; 15+ messages in thread
From: Stefan Monnier @ 2019-08-06  7:40 UTC (permalink / raw)
  To: Hendrik Tews; +Cc: 13400, Noam Postavsky

> complete. If the programmer cannot rely on the documentation to
> be complete here, he or she has no other choice than to assume
> that output can arrive anywhere and he/she _is_ plagued with the
> usual parallel programming problems.

While I largely agree with your points, I'll mention that we *are*
plagued, because lots of functions may (in some cases) end up calling
a blocking operation.  E.g. any call to a file function can block if the
file happens to be handled by Tramp, so any call to a function which
(transitively) calls a file function can itself block.

> It is about a few words making the documentation more precise,
> potentially saving somebody a painful debugging session of
> several hours - similar to what I went through in 2013. Back
> then, I was lucky because clearing the disk caches was enough to
> reproduce the problem. Today with SSD's it is probably much
> harder...

I think preventing recursive filter invocations (by default) would be
much better than warning the programmer about that odd possibility.


        Stefan






^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-05 22:37   ` Hendrik Tews
  2019-08-06  7:40     ` Stefan Monnier
@ 2019-08-08  1:15     ` Noam Postavsky
  2019-08-20 12:19       ` Noam Postavsky
  1 sibling, 1 reply; 15+ messages in thread
From: Noam Postavsky @ 2019-08-08  1:15 UTC (permalink / raw)
  To: Hendrik Tews; +Cc: 13400, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 2639 bytes --]

Hendrik Tews <hendrik@askra.de> writes:

> thanks for addressing this quite old bug report. I do have some
> comments:

Thanks for still following up even though the reply was so delayed.

>>> - Section "37.9 Receiving Output from Processes" does not list
>>>   process-send-string. How about other blocking I/O functions?
>>
>> In the attached patch, I've added a mention/xref for functions which send
>> data to processes.
>
> How about other blocking I/O functions?  When output is accepted
> inside process-send-string, then it probably is in all potentially
> blocking I/O functions?

As far as I know, all the blocking functions are listed in the Input to
Processes node which I xref'd.

>>> - Same in "37.9.2. Process Filter Functions"
>>
>> This section is repeated twice (I addressed the second instance below).
>
> I mentioned this section twice, because there are _two_
> documentation problems.

Aha, missed that, thanks.

>>> - Same in "37.4 Creating an Asynchronous Process" ,
>>>   process-send-string is neither waiting for input not time
>>>   delay.
>>
>> I don't see any mention of process-send-string in that section, nor how
>> it's relevant to the rest of this report.
>
> Come on, please read that section carefully. "Emacs accepts data
> from the process only while waiting for input or for a time
> delay" in there implies that Emacs is _not_ accepting data during
> process-send-string, because, as I wrote, 

Thanks, it's hard to pick out such details on the Nth time reading the
manual.

>>> - "37.7 Sending Input to Processes" says that filters can run
>>>   inside process-send-string, but it could be clearer about the
>>>   point that this can also happen inside the same filter for the
>>>   same process.
>>
>> I'm not really convinced that is necessary.
>
> It is about a few words making the documentation more precise,
> potentially saving somebody a painful debugging session of
> several hours

I'm just not sure anyone is going to notice such details when it really
matters.  In my experience the manual is more about having something
authoritative to point to when folks ask "why does X happen?".  But I've
added a parenthetical to the patch.

> Adding to the original bug report, I would suggest to restructure
> the documentation, such that there is only one section
> documenting all the functions in which process output could
> arrive and such that all the other sections only refer to that
> section. It should really not be the case that different sections
> make different and sometimes inconsistent statements about the
> same feature.

Yes, hence the xrefs.  See attached updated patch.


[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 4170 bytes --]

From 895b3e135828006732bde40d54f74b1d5d3957f2 Mon Sep 17 00:00:00 2001
From: Noam Postavsky <npostavs@gmail.com>
Date: Fri, 26 Jul 2019 23:20:37 -0400
Subject: [PATCH] Note that process filter can be called recursively
 (Bug#13400)

* doc/lispref/processes.texi (Asynchronous Processes): Note that input
may read when sending data as well.
(Output from Processes): Note that functions which send data may also
trigger reading from processes.
(Input to Processes, Filter Functions): Note that filter functions may
be called recursively.
---
 doc/lispref/processes.texi | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index a93f4db428..bd807cdcee 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -588,9 +588,8 @@ Asynchronous Processes
 parallel with Emacs, and Emacs can communicate with it using the
 functions described in the following sections (@pxref{Input to
 Processes}, and @pxref{Output from Processes}).  Note that process
-communication is only partially asynchronous: Emacs sends data to the
-process only when certain functions are called, and Emacs accepts data
-from the process only while waiting for input or for a time delay.
+communication is only partially asynchronous: Emacs sends and receives
+data to and from a process only when those functions are called.
 
 @cindex pty, when to use for subprocess communications
 @cindex pipe, when to use for subprocess communications
@@ -1200,8 +1199,9 @@ Input to Processes
 because the input buffer is full.  When this happens, the send functions
 wait a short while, accepting output from subprocesses, and then try
 again.  This gives the subprocess a chance to read more of its pending
-input and make space in the buffer.  It also allows filters, sentinels
-and timers to run---so take account of that in writing your code.
+input and make space in the buffer.  It also allows filters (including
+the one currently running), sentinels and timers to run---so take
+account of that in writing your code.
 
   In these functions, the @var{process} argument can be a process or
 the name of a process, or a buffer or buffer name (which stands
@@ -1416,9 +1416,10 @@ Output from Processes
 
   Output from a subprocess can arrive only while Emacs is waiting: when
 reading terminal input (see the function @code{waiting-for-user-input-p}),
-in @code{sit-for} and @code{sleep-for} (@pxref{Waiting}), and in
-@code{accept-process-output} (@pxref{Accepting Output}).  This
-minimizes the problem of timing errors that usually plague parallel
+in @code{sit-for} and @code{sleep-for} (@pxref{Waiting}), in
+@code{accept-process-output} (@pxref{Accepting Output}), and in
+functions which send data to processes (@pxref{Input to Processes}).
+This minimizes the problem of timing errors that usually plague parallel
 programming.  For example, you can safely create a process and only
 then specify its buffer or filter function; no output can arrive
 before you finish, if the code in between does not call any primitive
@@ -1594,14 +1595,10 @@ Filter Functions
   By default, the error output from the process, if any, is also
 passed to the filter function, unless the destination for the standard
 error stream of the process was separated from the standard output
-when the process was created (@pxref{Output from Processes}).
-
-  The filter function can only be called when Emacs is waiting for
-something, because process output arrives only at such times.  Emacs
-waits when reading terminal input (see the function
-@code{waiting-for-user-input-p}), in @code{sit-for} and
-@code{sleep-for} (@pxref{Waiting}), and in
-@code{accept-process-output} (@pxref{Accepting Output}).
+when the process was created.  Emacs will only call the filter
+function during certain function calls.  @xref{Output from Processes}.
+Note that if any of those functions are called by the filter, the
+filter may be called recursively.
 
   A filter function must accept two arguments: the associated process
 and a string, which is output just received from it.  The function is
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-05 18:31       ` Stefan Monnier
@ 2019-08-08  3:37         ` Noam Postavsky
  2019-08-08 13:36           ` Eli Zaretskii
  0 siblings, 1 reply; 15+ messages in thread
From: Noam Postavsky @ 2019-08-08  3:37 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 13400, hendrik

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> I'm pretty sure that while there might be use-cases for recursive
> invocation of filters, this is a very exceptional situation and the
> average programmer will not expect it and would be stumped if/when
> it happens.
>
> So the default should be to prevent it, with maybe some way to override
> it to cater to the exceptional case where recursive invocation
> is to be allowed.
>
> I think we could do that by setting a property on process object during
> filter invocation to postpone further filter invocations, and then the
> process filter could locally unset this property if it wants to allow
> recursive invocations.

Yeah, I suppose that would probably be better.  Although then we have
some potential weird edge cases like what happens when when changing the
property during a recursive invocation.






^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-08  3:37         ` Noam Postavsky
@ 2019-08-08 13:36           ` Eli Zaretskii
  2019-08-09 21:36             ` Stefan Monnier
  0 siblings, 1 reply; 15+ messages in thread
From: Eli Zaretskii @ 2019-08-08 13:36 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: hendrik, 13400, monnier

> From: Noam Postavsky <npostavs@gmail.com>
> Cc: Eli Zaretskii <eliz@gnu.org>,  13400@debbugs.gnu.org,  hendrik@askra.de
> Date: Wed, 07 Aug 2019 23:37:29 -0400
> 
> > So the default should be to prevent it, with maybe some way to override
> > it to cater to the exceptional case where recursive invocation
> > is to be allowed.
> >
> > I think we could do that by setting a property on process object during
> > filter invocation to postpone further filter invocations, and then the
> > process filter could locally unset this property if it wants to allow
> > recursive invocations.
> 
> Yeah, I suppose that would probably be better.  Although then we have
> some potential weird edge cases like what happens when when changing the
> property during a recursive invocation.

Hmm... I'm not sure I understand what would this mean in practice.
Suppose a process filter invokes some blocking API, which then calls
wait_reading_process_output, and 'pselect' tells us that same process
can be read from again.  How will we avoid calling the filter
recursively in this case, and what will we do instead of calling it?





^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-08 13:36           ` Eli Zaretskii
@ 2019-08-09 21:36             ` Stefan Monnier
  2019-08-10  1:39               ` Noam Postavsky
  0 siblings, 1 reply; 15+ messages in thread
From: Stefan Monnier @ 2019-08-09 21:36 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: hendrik, 13400, Noam Postavsky

> Hmm... I'm not sure I understand what would this mean in practice.
> Suppose a process filter invokes some blocking API, which then calls
> wait_reading_process_output, and 'pselect' tells us that same process
> can be read from again.

I think we shouldn't pass that process's handle to pselect.


        Stefan






^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-09 21:36             ` Stefan Monnier
@ 2019-08-10  1:39               ` Noam Postavsky
  2019-08-10  9:03                 ` Stefan Monnier
  0 siblings, 1 reply; 15+ messages in thread
From: Noam Postavsky @ 2019-08-10  1:39 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 13400, hendrik

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> Hmm... I'm not sure I understand what would this mean in practice.
>> Suppose a process filter invokes some blocking API, which then calls
>> wait_reading_process_output, and 'pselect' tells us that same process
>> can be read from again.
>
> I think we shouldn't pass that process's handle to pselect.

That sounds like it would equivalent to setting the process' filter
function to t while running its body.  If you try that with the example
in the OP, you get a deadlock, because the subprocess' pipe becomes full
as Emacs stops reading it, and its input pipe becomes full so Emacs gets
stuck when trying to send data to it.

I thought you meant something more like my make-buffered-filter example,
where Emacs would still read from the process, but not call the filter
function with the new data until the current invocation ends (i.e.,
Emacs would just temporarily save the data).





^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-10  1:39               ` Noam Postavsky
@ 2019-08-10  9:03                 ` Stefan Monnier
  0 siblings, 0 replies; 15+ messages in thread
From: Stefan Monnier @ 2019-08-10  9:03 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: 13400, hendrik

> That sounds like it would equivalent to setting the process' filter
> function to t while running its body.

Yes.

> If you try that with the example in the OP, you get a deadlock,
> because the subprocess' pipe becomes full as Emacs stops reading it,
> and its input pipe becomes full so Emacs gets stuck when trying to
> send data to it.

Indeed.  It's a classic problem with popen-like setups.

It's a problem if Emacs itself gets stuck preventing other things to
run, but otherwise I don't see it as a real problem: the OP's example
is artificial.

> I thought you meant something more like my make-buffered-filter example,
> where Emacs would still read from the process, but not call the filter
> function with the new data until the current invocation ends (i.e.,
> Emacs would just temporarily save the data).

That's another option.


        Stefan






^ permalink raw reply	[flat|nested] 15+ messages in thread

* bug#13400: 23.4; overlapping process filter calls
  2019-08-08  1:15     ` Noam Postavsky
@ 2019-08-20 12:19       ` Noam Postavsky
  0 siblings, 0 replies; 15+ messages in thread
From: Noam Postavsky @ 2019-08-20 12:19 UTC (permalink / raw)
  To: Hendrik Tews; +Cc: 13400, Stefan Monnier

> See attached updated patch.

I've pushed it to emacs-26.  Leaving the bug open for now, since we
might still want to actually change the behaviour.

615cff4258 2019-08-19T19:49:50-04:00 "Fix process filter documentation (Bug#13400)"
https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=615cff42580a3521c1a4ea7c3ec467eb8259e1c7






^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-08-20 12:19 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-10 10:11 bug#13400: 23.4; overlapping process filter calls Hendrik Tews
2019-07-27  3:38 ` Noam Postavsky
2019-07-27  8:24   ` Eli Zaretskii
2019-08-04  0:02     ` Noam Postavsky
2019-08-04 16:29       ` Eli Zaretskii
2019-08-05 18:31       ` Stefan Monnier
2019-08-08  3:37         ` Noam Postavsky
2019-08-08 13:36           ` Eli Zaretskii
2019-08-09 21:36             ` Stefan Monnier
2019-08-10  1:39               ` Noam Postavsky
2019-08-10  9:03                 ` Stefan Monnier
2019-08-05 22:37   ` Hendrik Tews
2019-08-06  7:40     ` Stefan Monnier
2019-08-08  1:15     ` Noam Postavsky
2019-08-20 12:19       ` Noam Postavsky

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).