Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(46)

Unified Diff: Modules/threadmodule.c

Issue 3641: thread._local, threading.local Python issue 1868 & 3710 SVN Base: http://svn.python.org/view/*checkout*/python/trunk/
Patch Set: threading_local4 - includes the unit test, fixes the missing error path decref Created 1 year, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side by-side-diff with in-line comments
Download patch
Index: Modules/threadmodule.c
===================================================================
--- Modules/threadmodule.c (revision 66142)
+++ Modules/threadmodule.c (working copy)
@@ -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,11 @@
goto err;
}
- if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
+ if (PyDict_SetItem(tdict, self->key, localdict) < 0) {
+ Py_DECREF(localdict);
goto err;
+ }
+ Py_DECREF(localdict);
return (PyObject *)self;
@@ -220,7 +222,6 @@
{
Py_VISIT(self->args);
Py_VISIT(self->kw);
- Py_VISIT(self->dict);
return 0;
}
@@ -230,7 +231,6 @@
Py_CLEAR(self->key);
Py_CLEAR(self->args);
Py_CLEAR(self->kw);
- Py_CLEAR(self->dict);
return 0;
}
@@ -253,6 +253,7 @@
Py_TYPE(self)->tp_free((PyObject*)self);
}
+/* Return borrowed reference to the local dict */
static PyObject *
_ldict(localobject *self)
{
@@ -278,10 +279,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 +291,39 @@
}
- /* 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);
+ if (v != NULL) {
+ return PyDict_SetItem(ldict, name, v);
+ } else {
+ int res;
+ res = PyDict_DelItem(ldict, name);
+ if ((res < 0) && PyErr_ExceptionMatches(PyExc_KeyError)) {
+ PyErr_SetObject(PyExc_AttributeError, name);
+ }
+ return res;
+ }
}
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 +369,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 +386,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)
« Lib/test/test_threading.py ('k') | no next file »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld r497