Help with a Python ASP C extension module ...

Mark Hammond mhammond at skippinet.com.au
Sat Mar 16 21:03:55 EST 2002


Eric Vasilik wrote:
> I am writing a C extension to Python.  The reason I am writing an
> extension is that I believe that the implementation of
> Response.BinaryWrite() in the Window's ASP extension (I am using
> Active State's Python 2.1) is not releasing the global interpreter
> lock.  

I am almost certain that it does.  All COM calls release the GIL. 
Response is an IDispatch object.  This means that the call is made via 
either PyIDispatch::Invoke, or PyIDispatch::InvokeTypes.  These release 
the lock.

 > I am getting very poor performace using it and I believe that
> my server is not taking advantage of writing out multiple streams
> because of the global lock.

I am not sure what makes you believe Reponse.Write is to blame.  It is 
more likely that another Python thread is "busy" somewhere other than 
Response.Write or fileIO.

> Instead of writing out a response with:
> 
>     Response.BinaryWrite( buffer( open( fileName, 'rb' ).read() ) )
> 
> I am now doing the following:
> 
>     PythonExt.binaryWriteFile( Response, fileName )

OK - but don't be surprised if you see pretty much the same thing.  You 
are removing a little Python overhead, but not alot.

> The difference between these two is that the first calls the default
> implementation of Response.BinaryWrite and the second calls an
> extension I have written which reads the file and writes it out to
> response, all while the interpreter lock is released.

The former Python version will do all the significant work (ie, the file 
open, read and response.write call) with the lock released too.  Some of 
the IDispatch mechanics will be avoided though, as will the multiple 
lock transitions involved in the Python version.

> My problem, is I cannot find any documentation on how to get a hold of
> the IResponse object from the Python Response object.  I need to get
> it so that I may call BinaryWrite on without going back into the
> Python interpreter.

Going via IResponse should speed things up a tiny bit too.  Basically, 
the "Response" object is a class instance, and the attribute "_oleobj_" 
is the PyIDispatch object.  So you need something like:

   if (!PyArg_ParseTuple("Os", &pyResponse, &filename)) ...
   PyObject *pydisp = PyObject_GetAttrString(pyResponse, "_oleobj_");
   if (!pydisp) ...
   // now get the object.
   if (!PyCom_InterfaceFromPyObject(pydisp,
           IID_IRESPONSE,
           (void **)&pResponse,
           FALSE /* None is not valid */ )) ...
    Py_DECREF(pydisp);
    ... use pResponse
    pResponse->Release();


Using PyCom_InterfaceFromPyObject() means you will need to include 
pythoncom.h, and link against pythoncomxx.lib - which means you will 
need to build pythoncom from sources - see 
http://starship.python.net/crew/mhammond/win32/BuildingExtensions.html

Mark.




More information about the Python-list mailing list