Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old December 28th, 2006, 03:45 PM
Robin Becker
Guest
 
Posts: n/a
Default per interpreter storage for C extensions

As part of some django usage I need to get some ReportLab C extensions into a
state where they can be safely used with mod_python.

Unfortunately we have C code that seems incompatible with mod_python and I'm
looking for ways to improve the situation.

Basically the main things that are wrong are all privately cached copies of
python variables. This sample code


static PyObject *_pdfmetrics_fonts = NULL;
static PyObject *_pdfmetrics_ffar = NULL;

...........
if(!_pdfmetrics_fonts){
res = PyImport_ImportModule("reportlab.pdfbase.pdfmetric s");
if(!res) ERROR_EXIT();
_o1 = _GetAttrString(res,"_fonts");
if(!_o1) ERROR_EXIT();
_o2 = _GetAttrString(res,"findFontAndRegister");
if(!_o2) ERROR_EXIT();
_pdfmetrics_fonts = _o1;
_pdfmetrics_ffar = _o2;
Py_DECREF(res); _o1 = _o2 = res = NULL;
}
if((res = PyObject_GetItem(_pdfmetrics_fonts,fontName))) return res;
............

illustrates the general problem. If called first by interpreter A I'll get the
values from interpreter A. When later called by interpreter B I'll be using the
wrong values and _pdfmetrics_ffar can alter the wrong interpreter's data.


The functions themselves are fairly small, but may be called many times so
they're worth speeding up.

Is there a simple/cheap way for C code to cache these sorts of module level
globals on a per interpreter basis? Is there even a way to tell which
interpreter I'm being called in?

Anything too costly will probably bust any speedup. Luckily I don't think we
have too many of these cached variables so it's possible we may be able to get
away with just dropping the caching for some and eliminating others.
--
Robin Becker

  #2  
Old December 30th, 2006, 12:55 AM
=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
Guest
 
Posts: n/a
Default Re: per interpreter storage for C extensions

Robin Becker schrieb:
Quote:
Is there a simple/cheap way for C code to cache these sorts of module
level globals on a per interpreter basis? Is there even a way to tell
which interpreter I'm being called in?
There is no cheap way to add to the interpreter state. As Chris Mellon
explains, you can use PyThreadState_Get()->interp to find the
interpreter state. I recommend to do the caching only in the
single-interpreter case (i.e. for the first interpreter).

Notice that comparing interpreter states by identity is somewhat
dangerous: the interpreter may have been deleted with you still
holding a pointer to it, and a new interpreter may get allocated
at the same address, making you believe it is the same interpreter.

Regards,
Martin
  #3  
Old December 30th, 2006, 12:55 PM
Robin Becker
Guest
 
Posts: n/a
Default Re: per interpreter storage for C extensions

Martin v. Löwis wrote:
Quote:
Robin Becker schrieb:
Quote:
>Is there a simple/cheap way for C code to cache these sorts of module
>level globals on a per interpreter basis? Is there even a way to tell
>which interpreter I'm being called in?
>
There is no cheap way to add to the interpreter state. As Chris Mellon
explains, you can use PyThreadState_Get()->interp to find the
interpreter state. I recommend to do the caching only in the
single-interpreter case (i.e. for the first interpreter).
>
Notice that comparing interpreter states by identity is somewhat
dangerous: the interpreter may have been deleted with you still
holding a pointer to it, and a new interpreter may get allocated
at the same address, making you believe it is the same interpreter.
.....
I can eliminate most of the problems by not keeping private pointers to
the cache variables.

What is worrying is that in the extension init we're creating an
exception and version string etc and holding a pointer to them in C; is
it safe to use the same exception in different interpeters? Currently
the exception is added to the module at init time, but my reading of the
documentation implies that all interpreters will see that exception as
it is copied from the first.
--
Robin Becker
  #4  
Old December 30th, 2006, 02:45 PM
=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
Guest
 
Posts: n/a
Default Re: per interpreter storage for C extensions

Robin Becker schrieb:
Quote:
What is worrying is that in the extension init we're creating an
exception and version string etc and holding a pointer to them in C; is
it safe to use the same exception in different interpeters?
It is safe as long as the base exception classes are also shared across
interpreters, otherwise, the hierarchical exception matching will break.
The builtin exceptions are all "global" (i.e. shared across
interpreters) (I believe).

In any case, it looks like that the "multiple interpreters" feature of
Python is just broken.

Regards,
Martin
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles