Jerry James wrote:
I wonder if this is related to a problem in the 21.5 series that
I've
been chasing for some time. The lstream code has changed somewhat from
21.4 to 21.5, but I wonder if the 2nd hunk of this patch:
http://list-archive.xemacs.org/xemacs-beta/200410/msg00100.html
is attempting to fix the same problem. Briefly, Lstream_close can lose
data if the process on the other end of the stream doesn't read stuff
fast enough. The referenced patch attempts to loop and push data into
the stream until it either encounters an error or succeeds in flushing
everything out. Does that approach also solve your problem? If so,
perhaps we can make common cause on finding a final solution to this
problem.
Well, it looks plausible that we're trying to solve similar problems,
but I'm not sure this patch would help me -- JDE needs to be able to
carry on its conversation after flushing the output from an individual
(process-send-string) call. It can't wait until the stream is closed
to be sure that all its data has been transmitted.
At least in my case, the problem arises because the output side of the
stream to be flushed is a file descriptor in _non-blocking_ mode. When
Lstream_flush_out() is called on such a stream, and its writer
method gets EAGAIN/EWOULDBLOCK from the fd because the pipe's full,
Lstream_flush_out() is allowed (reasonably enough, because it can't make
progress) to return 0. But it also sets a flag on the stream to record
that the reason it can't make progress is that the stream is blocked.
Unless I'm missing something, in the situation I'm in (getting
EWOULDBLOCK) the second hunk of the patch you refer to will spin in
tight loop until such time as the EWOULDBLOCK goes away. Spinning makes
it harder for other processes to get a look in, including the one
reading from the other end of the pipe.
In process-unix.c, unix_send_process() is also trying to handle the
EWOULDBLOCK case by repeatedly flushing the stream while
Lstream_was_blocked_p() remains true. However, it does give other
processes a chance by spending up to a second waiting for input
between flush attempts.
The problem my patch is addressing in unix_send_process() is that
the unpatched code fails to do the flush-and-wait-while-
Lstream_was_blocked_p dance for the very last chunk in an individual
(process-send-string).
In your case, does the data you want flushed go via
(process-send-string) and unix_send_process()? If it does, then I'd
expect my patch to help you. If not, it sounds like we both need
an lstream flushing function that can make a best effort to get the data
through in the face of Lstream_was_blocked_p(). Such a function would
presumably need to contain a flush-and-wait loop similar to the one
in unix_send_process().
At this point, I think it would be very helpful if our patches could be
reviewed by the author(s)/maintainer(s) of XEmacs's process-interaction
code. I don't know who that is -- could someone who does perhaps try
to attract their attention?
Cheers,
---- Dave