quetz-mod_python-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jeff Robbins" <je...@livedata.com>
Subject Re: MODPYTHON-195
Date Wed, 08 Nov 2006 11:07:22 GMT

You placed the fix in a better spot than I did.  I had placed it after the 
apr_pool_userdata stuff due to not understanding what that was all about. 
It makes better sense to simply test and exit the python_init() routine as 
quickly as possible in the Win32 parent process.  Your comment is good, too. 
I will test your version and confirm.


----- Original Message ----- 
From: "Graham Dumpleton" <grahamd@dscpl.com.au>
To: "Jeff Robbins" <jeffr@livedata.com>
Cc: "python-dev list" <python-dev@httpd.apache.org>
Sent: Wednesday, November 08, 2006 05:38
Subject: Re: MODPYTHON-195

> 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 
> 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

View raw message