Stas Bekman wrote:
Mark James wrote:
STDOUT is flushed prior to a fork to exec an external binary (rcs).
I understand the cause. But I hope that you agree with me that this is
an application's problem. If you haven't sent anything to STDOUT yet,
don't flush. And if this is not under your control, reopen STDOUT to
/dev/null before you call that piece of code, that flushes and then
re-tie STDOUT again.
(See t/response/TestModperl/request_rec_tie_api.pm)
I guess the best way to fix the problem in-application would be to
either run nph, or do the /dev/null redirect you suggest.
Interestingly, commenting out the pre-fork flush fixes the problem
under mod_perl because close in mod_perl seems to be a no-op rather
than a flush. If the close is also no problem under mod_cgi then
is there any real need for such a pre-fork flush in my script?
I see. But why is there no problem when using mod_cgi?
That's an interesting question. mod_cgi is a generic handler, which can
run applications written in any language. Therefore it has no clue of
what flush is. It simply creates a pipe to the application, and expects
the headers headers followed by the data.
In your case, when cgi script flushes STDOUT, nothing happens at all,
because there is no data to flush. So mod_cgi gets the headers and the
data and all is cool
When the same code is run under mod_perl, flush generates a special
bucket which is sent out to the filters chain, and since no headers are
generated yet, they get generated and sent out.
Well, even under mod_cgi a program can still fflush or write. The
difference between mod_cgi and mod_perl is that mod_cgi does not
activate the filter brigade until it has read all the headers.
Why would a perl handler script want to flush data down the filter chain
before it had finished writing all of it?
Here is an example: You have a long running process, you want the
headers to be sent immediately, but the data won't follow for a while.
So you create the headers, do $r->rflush, and later on send the data.
OK. So would there be a problem if mod_perl waited for the blank line
end of headers, or at least a Status header, before passing the buckets
down the line, just like mod_cgi?
mod_cgi uses spilling buckets, each of size 8K, to buffer script output,
including during the header scan, while mod_perl seems to scan the headers
when the first 8K buffer is either filled or flushed.