Mark James wrote:
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?

Since the mod_perl's internal STDOUT buffer isn't mangled if you re-tie it later, and it'll be always flushed at the end of the request, there is no *need* to flush on CLOSE. However in order to be consistent with perl fh close behavior, it probably needs to be changed to flush its buffer.


What do you think?

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.

Ah, of course!


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.

But in the case of mod_perl, this "event" is valid only for handlers which print their own headers, rather than using mod_perl API to set them. In the generic case, there is no way to tell whether a handler is going to set more headers or it has done with it.


I suppose that we could prevent flushing in the case the handler is configured to parse headers. Does it make sense?

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?

See above.


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.

I don't think this is related to the issue in question. Since the problem is what to do on flush.


Also we might have a problem if the headers to parse are bigger than the size of the buffer (8k). Do you think someone will ever need to send headers bigger than 8k?

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com



Reply via email to