[mod_python] Re: PyThreadState_Swap(NULL)

Graham Dumpleton grahamd at dscpl.com.au
Sun Aug 20 04:08:25 EDT 2006


On 20/08/2006, at 3:43 PM, Graham Dumpleton wrote:

> I'd have to look over your code and try and get my head around all  
> this
> stuff again, but I really think you will be fighting an uphill  
> battle to get
> something going which doesn't try and work in co-operation with
> mod_python some how.
>
> One of the first problems is that mod_python is the one to create the
> first interpreter and this first interpreter is special. If a  
> Python module
> has a C code component and it isn't written in just the right way  
> so as
> to work with interpreters other than the first, then it will have  
> problems.
> Usually this manifests as Python code running in a restricted  
> environment
> and not able to access various stuff, but other things could also  
> happen,
> including lock ups and crashes.
>
> The other problem you will have is that Apache on Win32 and also
> worker MPM on UNIX is multithreaded and even more work is required
> to get that to work properly. I don't see anything in your code that
> suggests that it takes multithreading and multiple interpreters into
> consideration.
>
> In the short term, using a separate Apache instance as you suggest
> will probably be your only quick solution. In the long term, I  
> still think
> using the proposed API for mod_python is the only way it is going to
> work.

Have been busy and have added minimal set of functions to mod_python
and exporting them for use in other modules. This code is now checked
into subversion trunk for 3.3.

As an example, here is how it could be used:

         PyObject *m = NULL;
         PyObject *o = NULL;
         PyObject *d = NULL;

         optfn_mp_acquire_interpreter("main_interpreter");

         request_obj = optfn_mp_get_request_object(r);

         m = PyImport_ImportModule("mod_python.testhandler");
         if (m) {
             d = PyModule_GetDict(m);
             o = PyDict_GetItemString(d, "handler");

             if (o) {
                 PyObject *a = NULL;
                 PyObject *r = NULL;

                 a = Py_BuildValue("(O)", request_obj);
                 r = PyEval_CallObject(o, a);
                 Py_DECREF(a);
                 if (r == NULL)
                     return HTTP_INTERNAL_SERVER_ERROR;

                 if (!PyInt_Check(r))
                     return HTTP_INTERNAL_SERVER_ERROR;

                 result = PyInt_AsLong(r);

                 Py_DECREF(r);
             }
             else {
                 ap_rputs("ERROR 2", r);
             }
         }
         else {
             ap_rputs("ERROR 1", r);
         }

         Py_XDECREF(request_obj);

         optfn_mp_release_interpreter();

Some proper logging could be performed for error cases, but general idea
here was to call mod_python.testhandler.handler from a response handler
registered from a C module distinct from mod_python.

The full code for this including Makefile's is attached to:

   http://issues.apache.org/jira/browse/MODPYTHON-165

You will need to modify the appropriate Makefile to specify where the  
Python
includes are though. By rights it should be a bit smarter and get  
includes and
defines etc by running Python to find them out. Will work out what  
needs to
be done to make the correct later.

In respect of your code, if it is layered properly and core module is  
distinct
and loadable from Python command line, all you need to do is import like
above and then call appropriate entry point.

Graham


More information about the Mod_python mailing list