Thanks for the answer! Or, is a solution like the one we already wrote good (see below or attached)? At least it does the job for us. Your solution (if implemented like you said) will wait always 4 times. In the one below, it waits only as long as the process is still running (for maximum 30 secs). And maybe you want to define this timeout in the configuration file.
Does this make sense?
Add instead of lines 379-380 the following lines:
// original code //////////////////////////////////////////////////////////////
// else
// proc_kill_force(&proc_table[i], main_server);
// new code ///////////////////////////////////////////////////////////////////
else {
// don't kill the process immediately, wait 30 sec
// every 0.5s test if the process has finished
int seconds = 30; // get from the config file or default
int steps = 2 * seconds;
int chunk = seconds * 1000000 / steps;
while (steps > 0) {
// if the process exited, break the loop
if (apr_proc_wait(&(proc_table[i].proc_id), &exitcode,
&exitwhy, APR_NOWAIT) != APR_CHILD_NOTDONE) {
break;
}
// chunk must be in micro-seconds
apr_sleep(chunk);
steps--;
}
if (steps != 0) {
proc_kill_force(&proc_table[i], main_server);
}
}
///////////////////////////////////////////////////////////////////////////////
On Tue, Oct 26, 2010 at 5:21 PM, Jeff Trawick <[email protected]> wrote:
> On Mon, Oct 25, 2010 at 10:30 AM, Gabriel Petrovay
> <[email protected]> wrote:
>> Hi,
>>
>> Maybe this gives you some hints. I have looked a little in the code of
>> mod_fcgi. In fcgid_pm_main.c (361) you have:
>>
>> /* Kill gracefully */
>> for (i = 0; i < proctable_get_table_size(); i++) {
>> if (proc_table[i].proc_pool)
>> proc_kill_gracefully(&proc_table[i], main_server);
>> }
>> apr_sleep(apr_time_from_sec(1));
>>
>> /* Kill with SIGKILL if it doesn't work */
>> for (i = 0; i < proctable_get_table_size(); i++) {
>> if (proc_table[i].proc_pool) {
>> if (apr_proc_wait(&(proc_table[i].proc_id), &exitcode, &exitwhy,
>> APR_NOWAIT) != APR_CHILD_NOTDONE) {
>> proc_table[i].diewhy = FCGID_DIE_SHUTDOWN;
>> proc_print_exit_info(&proc_table[i], exitcode, exitwhy,
>> main_server);
>> apr_pool_destroy(proc_table[i].proc_pool);
>> proc_table[i].proc_pool = NULL;
>> }
>> else
>> proc_kill_force(&proc_table[i], main_server);
>> }
>> }
>>
>> ---------------------------------
>>
>> You can see that mod_fcgi tries to gracefully kill the child processes
>> (proc_kill_gracefully).
>>
>> Than it waits 1 second. (probably hoping that the process finishes,
>> case in which the assumption is wrong; assume that we need 2 seconds
>> to shut-down).
>>
>> Than it starts to kill all the still running processes (/* Kill with
>> SIGKILL if it doesn't work */). Since my process is not finished, it
>> returns in line 371 APR_CHILD_NOTDONE (70006) so proc_kill_force() is
>> called in line 380.
>>
>> So that is why my process is killed at random times during shutdown.
>>
>>
>> Is this a bug? or am I missing something?
>
> IMO this should work in a similar manner to the
> ap_reclaim_child_processes functions used by Unix MPMs:
>
> kill-gracefully
> wait
> kill-gracefully
> wait
> kill-gracefully
> wait
> kill-forcefully (this starts at about 9 seconds)
> wait
> giveup
>
> though mod_fcgid doesn't necessarily need so many iterations or as
> large a delay.
>
> I'll plan to code up a patch for this in the next day or so.
>
--
MSc Gabriel Petrovay
Mobile: +41(0)787978034
www.28msec.com
fcgid_pm_main.c
Description: Binary data
