Exploiting Dual Core's with Py_NewInterpreter's separated GIL ?
"Martin v. Löwis"
martin at v.loewis.de
Tue Nov 7 13:11:47 EST 2006
Ross Ridge schrieb:
> The thread that shares it increments the reference count before passing
> its address to directly another thread or indirectly through a shared
> container.
To make a specific example, consider this fragment from
Objects/fileobject.c:
static PyObject *
file_repr(PyFileObject *f)
{
if (PyUnicode_Check(f->f_name)) {
...
Now, assume there wasn't a GIL protecting this all, and also
assume f_name was a mutable member (which it currently isn't).
Then, this access wouldn't be thread-safe: This code roughly
translates to
reg_x = f->f_name
push reg_x
call PyUnicode_Check (assuming this was a function and
not a macro)
Meanwhile, another process might perform
old = f->f_name;
f->f_name = new;
Py_DECREF(old);
i.e. change the file name. Now, it might be that they
interleave this way:
reg_x = f->f_name
old = f->f_name
f->f_name = new
Py_DECREF_old
push reg_x
call PyUnicode_Check
which would now operate on a deallocated object.
To fix this, one might think that we need
Py_INCREF(f->f_name)
if(Py_UnicodeCheck(f->f_name))
...
Py_DECREF(f->f_name)
However, this would not help, because the
first incref translates to
reg_x = f->f_name
LOCK INC f->ob_refcnt
which again leaves a race condition where the
INCREF operation comes "too late".
How would you propose to fix file_repr to prevent such
a race condition?
Regards,
Martin
More information about the Python-list
mailing list