This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author amaury.forgeotdarc
Recipients Rhamphoryncus, amaury.forgeotdarc, barry, benjamin.peterson, donmez, gvanrossum, jnoller, mark.dickinson, paulmelis, roudkerk, tebeka
Date 2008-06-28.23:41:25
SpamBayes Score 0.0052051763
Marked as misclassified No
Message-id <1214696488.1.0.0775359456322.issue3088@psf.upfronthosting.co.za>
In-reply-to
Content
After 4 hours spent with the debugger I think I have an explanation and
a correction of one of the problems.
Note that this only affects the "Manager" tests.

- The threading.local type overrides getattr and setattr: on every call,
it fetches a dictionary stored in the current ThreadState, and installs
it in its self->dict member, allowing the regular
PyObject_Generic[Get|Set]Attr functions to actually work on thread-local
data.
- Of course, for this to work the GIL must not be released in any way
between the moment self->dict is set, until object's dictionary is
retrieved inside PyObject_Generic[Get|Set]Attr. This condition makes the
code a bit fragile.
With current 2.6b1, there is no path in PyObject_Generic[Get|Set]Attr
that releases the GIL before the dict is retrieved - no decref, no jump
into python code (at least when the attribute name is a string). It's
almost a miracle, indeed.
- The problem is in threadmodule.c, the paragraph starting at line 285:
the first time the local object is accessed, it calls the __init__
method of the threading.local derived class. And this calls python code,
and can release the GIL.
- The consequences are dramatic: this let the possibility for another
thread to start, use the same local object, install its thread-local
dict in self->dict, and stop here; the first thread will wake up with
the wrong dict...
- in the multiprocessing case, a remote call to a synchronization
function grabs the wrong channel, and get bogus results... hence the
"cannot wait on un-aquired (sic) lock" message.

The actual correction is very short: only one "else" to remove... Here
is a patch with a test.
History
Date User Action Args
2008-06-28 23:41:28amaury.forgeotdarcsetspambayes_score: 0.00520518 -> 0.0052051763
recipients: + amaury.forgeotdarc, gvanrossum, barry, tebeka, mark.dickinson, Rhamphoryncus, donmez, paulmelis, roudkerk, benjamin.peterson, jnoller
2008-06-28 23:41:28amaury.forgeotdarcsetspambayes_score: 0.00520518 -> 0.00520518
messageid: <1214696488.1.0.0775359456322.issue3088@psf.upfronthosting.co.za>
2008-06-28 23:41:27amaury.forgeotdarclinkissue3088 messages
2008-06-28 23:41:26amaury.forgeotdarccreate