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

Hi there monks, I'm in a desperate need for your wisdom!
I'm creating a FastCGI application and I have a problem (for those of you, who are not familar with fcgi - it's a cgi environment where the interpreter is started only once and inside your code you have one while loop, which is used to accept the requests). Well, in that case I can't use the exit function in order to stop the program executing any further, because the whole interpreter will exit. The solution is simple - just use next; instead of exit;. In my case the code look like this:

LOOP: while(accept()) { ... some code... if(wanna_exit()) {&end_request;} } sub end_request {local $^W = 0; next LOOP;}


this code works fine (there is a warning when we exit from the subroutine by calling next; but that's fine)

My problem is when I call &end_request from a different package instead the one LOOP was defined in. I get a fatal error saying that LOOP wasn't defined in the current package. I must rely on the labels, because in the main loop I might have more while loops. Can I make LOOP to be somehow global for all packages? Any other solutions?

Replies are listed 'Best First'.
Re: Labels, while loops and FastCGI
by gaal (Parson) on Aug 01, 2004 at 18:37 UTC
    An appropriate idiom for this kind of thing is to use die with a special token:

    use constant END_REQUEST => "END_REQUEST\n"; sub end_request { die END_REQUEST } REQUEST: while(accept()) { eval { # process request 1; } or do { next REQUEST if $@ eq END_REQUEST; die $@; # propagate real errors }; }
Re: Labels, while loops and FastCGI
by ysth (Canon) on Aug 01, 2004 at 18:57 UTC
    Labels aren't package-specific; perl will go back up the calling stack until it finds an enclosing loop with the specified label.

    So either you aren't in the middle of that while loop, or there's a bug in perl here.

    Simple tests don't fail for me; can you come up with some code that shows the problem?

      gaal, your solution is a very nice one and with some modifications will perfectly fit in my program. Thank you.

      ysth, I wrote a sample code to show how my program works and then I realized you were right - labels work fine if you call them from different packages. In my situation the program fails because I call end_request from $SIG{__DIE__}.
      This is the sample code:

      #!/usr/bin/perl package A; $SIG{__DIE__} = sub { end_request(@_); }; sub end_request { print @_; next LOOP; } print "start\n"; $x = 0; LOOP: while($x != 5) { $x++; #die "die\n" if $x == 3; end_request("die\n") if $x == 3; } print "end\n";


      If you use it like this it will work, but if you uncomment the #die "die\n" if $x == 3; line you will get a Label not found for "next LOOP" error. Using perl 5.8.4.