quetz-mod_python-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Graham Dumpleton <grah...@dscpl.com.au>
Subject Re: MODPYTHON-195
Date Wed, 08 Nov 2006 10:38:30 GMT

On 07/11/2006, at 10:51 PM, Jeff Robbins wrote:

> Graham,
>
> The problem on Win32 is that (I believe) we never want to  
> initialize Python in the persistent parent process.  All the web  
> action is in the child process which is long-lived and it is this  
> child process that maintains the thread pool which services web  
> requests.

FWIW, in UNIX the initialisation of Python in the parent process is a  
good thing
as it means it is only done once no matter how many child processes  
there
are. This is because child processes are created as a fork of the  
parent process
and so they inherit the already initialised Python interpreter,  
thereby meaning
initialisation of the child process is quicker.

Since Win32 doesn't have an equivalent of fork, when the child process
is created the full Python initialisation is done anyway. Thus  
avoiding the
initialisation of Python in the parent is probably reasonable.

> The parent process as far as I can tell sits there to support  
> restarting the child process and support the Win32 Service Control  
> Manager (SCM) which has a protocol for how a process must respond  
> to certain messages in order to be a service on Win32.
>
> I do not know how to use flags alone to distinguish the two  
> processes.  The code I put in is not trying to restrict a call to  
> python_init() to only happen once in the parent process.  It is  
> preventing python_init() from initializing Python in the parent  
> process.
>
> I hope this clarifies things somewhat.
>
> I want to note here that mpm_winnt.c line 1108 looks like this:
>
> /* AP_PARENT_PID is only valid in the child */
> pid = getenv("AP_PARENT_PID");
> if (pid)
> {
> /* This is the child */
>
> This environmental is how it knows to run certain code only in the  
> child process.
>
> In summary,
>
> if we do not want to run python_init() in the special Win32 parent  
> process, we need a way to distinguish this parent process from the  
> child process in which we DO want to run python_init().   The code  
> which maintains this dual process architecture (undoubtedly in  
> support of the Win32 service architecture) uses an environmental  
> that it purposefull creates and injects into the child process  
> "AP_PARENT_PID".  I don't see how we can do better than use this  
> same distinguishing characterisic to know not to run python_init()  
> in the parent process.

As it stands I just may have to take you word on this as I don't have  
first hand
access to Win32 platform (and don't want to) to experiment. The  
AP_PARENT_PID
environment variable is at least present in all Apache 2.0 and 2.2  
versions that
we support, so at least okay for a while if we rely on that. In the  
future, if Apache
changes this, we will just need to accommodate any new/official way  
of determining
it.

Anyway, is the following what you are expecting and is it placed  
where you expect
it within the python_init() function?

     static int initialized = 0;

#ifdef WIN32
     /* No need to run python_init() in Win32 parent processes as
      * the lack of fork on Win32 means we get no benefit as far as
      * inheriting a preinitialized Python interpreter. Further,
      * upon a restart on Win32 platform the python_init() function
      * will be called again in the parent process but without some
      * resources allocated by the previous call having being
      * released properly, resulting in memory and Win32 resource
      * leaks.
      */
     if (!getenv("AP_PARENT_PID"))
         return OK;
#endif /* WIN32 */

     apr_pool_userdata_get(&data, userdata_key, s->process->pool);
     if (!data) {
         apr_pool_userdata_set((const void *)1, userdata_key,
                               apr_pool_cleanup_null, s->process->pool);
         return OK;
     }



Graham

Mime
View raw message