Index: Modules/threadmodule.c =================================================================== --- Modules/threadmodule.c (Revision 66053) +++ Modules/threadmodule.c (Arbeitskopie) @@ -164,7 +164,6 @@ PyObject *key; PyObject *args; PyObject *kw; - PyObject *dict; } localobject; static PyObject * @@ -172,6 +171,7 @@ { localobject *self; PyObject *tdict; + PyObject *localdict; if (type->tp_init == PyBaseObject_Type.tp_init && ((args && PyObject_IsTrue(args)) @@ -189,13 +189,12 @@ self->args = args; Py_XINCREF(kw); self->kw = kw; - self->dict = NULL; /* making sure */ self->key = PyString_FromFormat("thread.local.%p", self); if (self->key == NULL) goto err; - self->dict = PyDict_New(); - if (self->dict == NULL) + localdict = PyDict_New(); + if (localdict == NULL) goto err; tdict = PyThreadState_GetDict(); @@ -205,8 +204,9 @@ goto err; } - if (PyDict_SetItem(tdict, self->key, self->dict) < 0) + if (PyDict_SetItem(tdict, self->key, localdict) < 0) goto err; + Py_DECREF(localdict); return (PyObject *)self; @@ -220,7 +220,6 @@ { Py_VISIT(self->args); Py_VISIT(self->kw); - Py_VISIT(self->dict); return 0; } @@ -230,7 +229,6 @@ Py_CLEAR(self->key); Py_CLEAR(self->args); Py_CLEAR(self->kw); - Py_CLEAR(self->dict); return 0; } @@ -253,6 +251,7 @@ Py_TYPE(self)->tp_free((PyObject*)self); } +/* Return borrowed reference to the local dict */ static PyObject * _ldict(localobject *self) { @@ -278,10 +277,6 @@ return NULL; } - Py_CLEAR(self->dict); - Py_INCREF(ldict); - self->dict = ldict; /* still borrowed */ - if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init && Py_TYPE(self)->tp_init((PyObject*)self, self->args, self->kw) < 0) { @@ -294,39 +289,30 @@ } - /* The call to tp_init above may have caused another thread to run. - Install our ldict again. */ - if (self->dict != ldict) { - Py_CLEAR(self->dict); - Py_INCREF(ldict); - self->dict = ldict; - } - return ldict; } static int local_setattro(localobject *self, PyObject *name, PyObject *v) { - PyObject *ldict; - - ldict = _ldict(self); + PyObject *ldict = _ldict(self); if (ldict == NULL) return -1; - return PyObject_GenericSetAttr((PyObject *)self, name, v); + return PyDict_SetItem(ldict, name, v); } static PyObject * local_getdict(localobject *self, void *closure) { - if (self->dict == NULL) { + PyObject *ldict = _ldict(self); + if (ldict == NULL) { PyErr_SetString(PyExc_AttributeError, "__dict__"); return NULL; } - Py_INCREF(self->dict); - return self->dict; + Py_INCREF(ldict); + return ldict; } static PyGetSetDef local_getset[] = { @@ -372,7 +358,7 @@ /* tp_dict */ 0, /* internal use */ /* tp_descr_get */ 0, /* tp_descr_set */ 0, - /* tp_dictoffset */ offsetof(localobject, dict), + /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ local_new, @@ -389,10 +375,6 @@ if (ldict == NULL) return NULL; - if (Py_TYPE(self) != &localtype) - /* use generic lookup for subtypes */ - return PyObject_GenericGetAttr((PyObject *)self, name); - /* Optimization: just look in dict ourselves */ value = PyDict_GetItem(ldict, name); if (value == NULL)