-1.  The problems detailed in the messages are a misconfigured server, not
a bug in the code.  The threaded MPM should count ALL idle threads,
whether they are a part of the process that was just told to die or not.
Any idle threads that are a part of the process that was just told to die
will be dead the next time idle_server_maintenance is run, so everything
works out well in the end.

You must count the non-idle threads of the server that was told to die,
because if you don't you take the real chance of going over MaxClients.

Also, the process_status field is going away soon.  It isn't used
anywhere, and it isn't needed.

Ryan

On Sat, 14 Jul 2001, GUMMALAM,MOHAN (HP-Cupertino,ex2) wrote:

> I propose the following patch [PATCH A]: It will partially fix the unwanted
> child deaths problem (symptoms mentioned in the mails included below).  It
> fixes the problem by making sure that perform_idle_server_maintenance() does
> not count the threads of the process that recd the POD, in the calculation
> of idle_thread_count.  To do that I have used
> ap_scoreboard_image->parent[process_slot]->process_status field.  I am
> temporarily using an already defined value, SB_IDLE_DIE.  If the general
> idea is acceptable, I can work on solidifying the details.  PATCH A is
> attached below.
>
> However this patch exposes another problem in the code - by this new fix,
> although the untargetted childs do not get a POD, the targetted child
> process does not die immediately either.  Here is why that happens:  In the
> worker_thread() routine in threaded.c, at the instant when worker 1.0
> (represented in the <process_slot>.<thread_slot> format, i.e, 1 is the
> process_slot and 0 is the thread_slot) gets the POD, the remaining threads
> of process 1 are all waiting at the apr_lock_acquire(accept_mutex).  If the
> web-server is really idle, the chances are slim that all the remaining
> worker threads for process 1 would acquire the lock in a very short time.
> As an effect, the remaining worker threads of process 1 do not die
> immediately.  To resolve this:
>
> SOLUTION 1:  I plan to temporarily implement a new
> apr_lock_acquire_timeout() function, which would cause the threads waiting
> on the mutex to give-up after sometime.  The piece of code would look
> something like this:
>
> while ((rv = SAFE_ACCEPT(apr_lock_acquire_timeout(accept_mutex, timevalue)))
>       != APR_SUCCESS) {
>       if (check_if_timer_popped)
>               if (workers_may_exit)
>                       break;
>       else {                         /* apr_lock_acquire failed */
>               ap_log_error(....);
>               workers_may_exit = 1;
>       }
> }
>
> I know that this would cause some performance impact, but my guess is that
> it would not be a lot, especially if we keep the timevalue reasonably high.
> However, in order to get the functionality of
> perform_idle_server_maintenance() working right, we _will_ have to implement
> the above solution (or maybe something similar)!
>
> SOLUTION 2: One could use a slightly more _involved_ approach, where the
> dying thread could send a signal to its sibling threads, each of which will
> then handle that signal with a graceful exit.
>
> SOLUTION 3: We could turn our heads the other way by not worrying about this
> situation at all, since these threads would eventually die (when more
> requests are handled by the webserver).  However, by ignoring the problem,
> the purpose of perform_idle_server_maintenance() would be lost!!
>
> Please respond with your thought, and if there are no objections, I will go
> ahead and post a patch for SOLUTION 1 sometime soon.
>
> Thanks,
> Mohan
>
> ************************* Start PATCH A ********************************
> --- server/mpm/threaded/threaded.c.orig Tue Jul  3 06:58:10 2001
> +++ server/mpm/threaded/threaded.c      Fri Jul 13 18:28:44 2001
> @@ -495,7 +495,7 @@
>  }
>
>  /* Sets workers_may_exit if we received a character on the pipe_of_death */
> -static void check_pipe_of_death(void)
> +static void check_pipe_of_death(int process_slot)
>  {
>      apr_lock_acquire(pipe_of_death_mutex);
>      if (!workers_may_exit) {
> @@ -511,6 +511,7 @@
>          else {
>              /* It won the lottery (or something else is very
>               * wrong). Embrace death with open arms. */
> +           ap_scoreboard_image->parent[process_slot].process_status =
> SB_IDLE_DIE;
>              workers_may_exit = 1;
>          }
>      }
> @@ -584,7 +585,7 @@
>              if (event & APR_POLLIN) {
>                  /* A process got a signal on the shutdown pipe. Check if
> we're
>                   * the lucky process to die. */
> -                check_pipe_of_death();
> +                check_pipe_of_death(process_slot);
>                  continue;
>              }
>
> @@ -972,6 +973,9 @@
>         int status = SERVER_DEAD;
>         int any_dying_threads = 0;
>         int any_dead_threads = 0;
>
> +
> +       if (ap_scoreboard_image->parent[i].process_status == SB_IDLE_DIE)
> +           continue;
>
>         if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate)
>             break;
> ************************* End PATCH A ********************************


_____________________________________________________________________________
Ryan Bloom                              [EMAIL PROTECTED]
Covalent Technologies                   [EMAIL PROTECTED]
-----------------------------------------------------------------------------

Reply via email to