bollock has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I'm using CGI.pm's upload_hook functionality to write yet another upload-with-progress module.

It now works well, but I experienced a problem along the way and would like to get further input; basically, on files bigger than 2.5M it would stall, needing to be killed.

The test script runs inside of a standard CGI environment. The hook merely computed progress, then wrote to a log using the write_file function from File::Slurp.

I progressively ruled out buffering, memory footprint, and even debugged CGI.pm to no avail.

After a while I guessed that it might be running up against per-process file descriptor limits, and confirmed it by switching to IO::File, and building the hook as a closure which closed over the open IO::File object.

My question is: Why would the script stall?
Should it not just die in some way?

Replies are listed 'Best First'.
Re: Exhausting filehandles behaviour?
by Akhasha (Scribe) on Feb 14, 2006 at 20:21 UTC
    Without a relevant code example its hard to say what's going on. I would expect it to die if it exhausted the FDs available to the process. Looking at the latest source of File::Slurp, write_file() closes its filehandle in the normal course of events, and doesn't catch exceptions that would be thrown by resource exhaustion.

    I wonder if there is an error in the httpd log.

      Firstly, erroneousBollock == bollock. Sorry for any confusion.

      Hmmmmm, well this is embarassing, it seems that my test case which was stalling (no errors in apache log, logfile showed progress up to ~2.5MB) is now not failing. :-/

      Here is the test-case anyway.
      use strict; use warnings; use CGI qw(:all); use File::Slurp qw(write_file); sub hook { my ($file, $buffer, $bytes, $data) = @_; write_file('/tmp/uplog', {append => 1}, "[$file][$bytes][$data]"); } my $q = CGI->new(\&hook, 'AppName'); my $f = $q->param('upload_file'); print header(), "Done.";
      So the normal behaviour would be to die, not block, as I thought.

      ~2.5MB / 4k blocks -> ~640 handles. Not that many I guess.