[Python-Dev] Extension modules, Threading, and the GIL

David Abrahams dave@boost-consulting.com
Mon, 30 Dec 2002 23:11:06 -0500


martin@v.loewis.de (Martin v. L=F6wis) writes:

> David Abrahams <dave@boost-consulting.com> writes:
>
>> There was no deadlock, as I've said.=20=20
>
> Yes, you only said this was a no-no, in
>
> http://mail.python.org/pipermail/python-dev/2002-December/031449.html
>
> I inferred from that (apparently incorrectly) that the no-no is a
> deadlock.

In that very message, I also wrote:

    I realize that the docs for PyEval_AcquireLock() say: "If this
    thread already has the lock, a deadlock ensues", but the behavior
    we're seeing is consistent with a scenario where trying to acquire
    an already-held is a no-op and releasing it is unconditional.
    Eventually the GIL release in B's callback takes effect and when A
    returns to Python there is no thread state.

>> The symptom is that Python complains at some point that there's no
>> thread state.  It goes away if A releases the GIL before calling
>> into Qt, and reacquires the GIL afterwards.
>
> Now I'm confused. In
>
> http://mail.python.org/pipermail/python-dev/2002-December/031424.html
>
> you said "A must also release the GIL"=20

Yes, that's the inevitable conclusion.

> and then "the author of A may have had no reason to believe anyone
> would install Python callbacks in Q". From that I inferred that A
> does *not* release the GIL (as the author had no reason to).

Yes, not releasing the GIL in A was fine until B came along and
installed callbacks in Q which acquire the GIL.
>
> Now you are saying that A releases the GIL. Which one it is?

No, I am not saying A releases the GIL.  I am saying that A that must
release the GIL if it is to work properly in the presence of B.  A is
currently broken in the presence of B.  The addition of B to the
system places a new constraint on A.

>> I speculate that the callback releases the GIL when it is finished,
>> so that when A returns to Python there is no current thread.
>
> That would be a bug in the callback.=20

Not if it has previously acquired the GIL.

> If there was a thread state when it was called, there should be a
> thread state when it returns.

Yes, the whole problem is that there's no way to know whether there's
a thread state.

>> Hmm, it seems as though a mutex-protected record of which thread is
>> currently holding the GIL should be enough to handle it.=20
>
> It depends on what "it" is, here. This one?
>
> Q: Is there a way to find out whether the current thread holds the GIL?
>
> If so, a mutex-protected record might work, but also might be
> expensive.

Yes.  I assume that acquiring the GIL already needs to do
synchronization, though.

--=20
                       David Abrahams
   dave@boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution