[LA.pm] Problem with FastCGI under Apache 2
Kevin Scaldeferri
kevin+lapm at scaldeferri.com
Thu Feb 9 15:47:29 PST 2006
On Feb 9, 2006, at 3:21 PM, Benjamin J. Tilly wrote:
> "Loren Osborn" <lsosborn at dis-sol-inc.com> wrote:
>>
>> We are having a serious problem with signals in FastCGI under Apache 2
>> and could use any assistance you could offer. It appears that FastCGI
>> is attempting to shutdown a perl script that it's running by sending
>> it
>> a SIGTERM, but the process is asleep and the signal is queued for when
>> the process is next awakened. When FastCGI gets a request for a page
>> of
>> the type that was sent the SIGTERM, it sees the process as still
>> alive,
>> and sends it another request. The process is awakened, sees the
>> SIGTERM,
>> and dies without providing a response to FastCGI. FastCGI then
>> produces
>> an error indicating that the script produced no output.
>
> Set the environment variable PERL_SIGNALS to unsafe for the script.
>
> Here is the issue. Perl has 2 ways to handle signals. One is safe,
> which will interrupt and handle the error when the current opcode
> finishes. The other is unsafe, which uses setlongjmp to break out of
> whatever Perl is doing right now.
>
This is mostly true, but has some caveats, since perl doesn't actually
mask the signals during the execution of an opcode.
When you say that the process is "asleep", what do you mean exactly?
Normally, when a perl process is blocked in a system call and a signal
comes in, the system call will be interrupted and the signal will be
handled immediately. If you are using safe signals, the internal
signal handler just sets a flag and continues the opcode (immediately
after the system call), then calls the Perl signal hander at the end of
the opcode. If you are using unsafe signals, the internal signal
handler will immediately execute the Perl signal handler, then normal
execution will resume with the next instruction after the system call.
So, if you are in a system sleep() call, or select(), or flock(), or
anything like that, the SIGTERM should break you out essentially
immediately, regardless of safe vs. unsafe signals.
The usual place that you see this is when you're calling something like
a database client, which does some signal masking internally. In that
case, the signal will be blocked until the database call finishes.
I don't know exactly what's going on with your situation, but I would
definitely recommend that you _NOT_ use unsafe signals. The thing is,
they're not safe. There are really bizarro things that can happen to
perl's internal state as a result of using them. It's not as nice as
perl just segfaulting if something bad happens. You can end up with
silently incorrect behavior after the delivery of an unsafe signal. I
hope this example will scare you away from ever using unsafe signals in
an important application:
http://kevin.scaldeferri.com/blog/2004/03/04/unsafe.html
-kevin
More information about the Losangeles-pm
mailing list