[ 
http://issues.apache.org/jira/browse/MODPYTHON-77?page=comments#action_12320935 
] 

Graham Dumpleton commented on MODPYTHON-77:
-------------------------------------------

I'm -1 for it going into next beta. I too want to understand it first as use of 
thread states can be very tricky.

I don't have source to refer to at hand so can't check again this instant, but 
is there a specific reason the interpreter data has to be stashed into the main 
interpreter itself? Is this so some specific extension can access it? Am wary 
of a solution which might be specific to making a particular extension work. 
Would want to know for sure that the specific extension is doing the correct 
things in the first place.

> The multiple interpreter concept of mod_python is broken for Python extension 
> modules since Python 2.3
> ------------------------------------------------------------------------------------------------------
>
>          Key: MODPYTHON-77
>          URL: http://issues.apache.org/jira/browse/MODPYTHON-77
>      Project: mod_python
>         Type: Bug
>   Components: core
>     Versions: 3.1.4
>  Environment: Python >= 2.3
>     Reporter: Boyan Boyadjiev
>  Attachments: diff.txt, diff2.txt, diff3.txt, mod_python.c
>
> The multiple interpreter concept of mod_python is broken for Python extension 
> modules since Python 2.3 because of the PEP 311 (Simplified Global 
> Interpreter Lock Acquisition for Extensions):
> ...
> Limitations and Exclusions
>     This proposal identifies a solution for extension authors with
>     complex multi-threaded requirements, but that only require a
>     single "PyInterpreterState".  There is no attempt to cater for
>     extensions that require multiple interpreter states.  At the time
>     of writing, no extension has been identified that requires
>     multiple PyInterpreterStates, and indeed it is not clear if that
>     facility works correctly in Python itself.
> ...
> For mod_python this means, that complex Python extensions won't work any more 
> with Python >= 2.3, because they are supposed to work only with the first 
> interpreter state initialized for the current process (a problem we 
> experienced). The first interpreter state is not used by mod_python after the 
> python_init is called. 
> One solution, which works fine for me, is to save the first interpreter state 
> into the "interpreters" dictionary in the function python_init 
> (MAIN_INTERPRETER is used as a key):
> static int python_init(apr_pool_t *p, apr_pool_t *ptemp,
>                        apr_pool_t *plog, server_rec *s)
> {
>     ...
>     /* initialize global Python interpreter if necessary */
>     if (! Py_IsInitialized())
>     {
>         /* initialze the interpreter */
>         Py_Initialize();
> #ifdef WITH_THREAD
>         /* create and acquire the interpreter lock */
>         PyEval_InitThreads();
> #endif
>         /* create the obCallBack dictionary */
>         interpreters = PyDict_New();
>         if (! interpreters) {
>             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, s,
>                          "python_init: PyDict_New() failed! No more memory?");
>             exit(1);
>         }
>         {   
>             /*
>             Workaround PEP 311 - Simplified Global Interpreter Lock 
> Acquisition for Extensions
>             BEGIN
>             */
>             PyObject *p = 0;
>             interpreterdata * idata = (interpreterdata 
> *)malloc(sizeof(interpreterdata));
>             PyThreadState* currentThreadState = PyThreadState_Get();
>             PyInterpreterState *istate = currentThreadState->interp;
>             idata->istate = istate;
>             /* obcallback will be created on first use */
>             idata->obcallback = NULL;
>             p = PyCObject_FromVoidPtr((void ) idata, NULL); /*p->refcout = 1*/
>             PyDict_SetItemString(interpreters, MAIN_INTERPRETER, p); 
> /*p->refcout = 2*/
>             Py_DECREF(p); /*p->refcout = 1*/
>             /*
>             END
>             Workaround PEP 311 - Simplified Global Interpreter Lock 
> Acquisition for Extensions
>             */
>         }
>         /* Release the thread state because we will never use
>          * the main interpreter, only sub interpreters created later. */
>         PyThreadState_Swap(NULL);
> #ifdef WITH_THREAD
>         /* release the lock; now other threads can run */
>         PyEval_ReleaseLock();
> #endif
>     }
>     return OK;
> }
> Another change I've made in the attached file is to Py_DECREF(p) in 
> get_interpreter, which will remove leaky reference to the PyCObject with the 
> interpreter data. This was not a real problem, but now I see fewer leaks in 
> BoundsChecker :-).

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira

Reply via email to