mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
Merged revisions 84344 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r84344 | antoine.pitrou | 2010-08-28 20:17:03 +0200 (sam., 28 août 2010) | 4 lines Issue #1868: Eliminate subtle timing issues in thread-local objects by getting rid of the cached copy of thread-local attribute dictionary. ........
This commit is contained in:
parent
06509381a8
commit
fcd2a7960c
6 changed files with 182 additions and 91 deletions
111
Objects/object.c
111
Objects/object.c
|
|
@ -911,7 +911,7 @@ _PyObject_NextNotImplemented(PyObject *self)
|
|||
/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */
|
||||
|
||||
PyObject *
|
||||
PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
|
||||
_PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict)
|
||||
{
|
||||
PyTypeObject *tp = Py_TYPE(obj);
|
||||
PyObject *descr = NULL;
|
||||
|
|
@ -971,37 +971,38 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
|
|||
}
|
||||
}
|
||||
|
||||
/* Inline _PyObject_GetDictPtr */
|
||||
dictoffset = tp->tp_dictoffset;
|
||||
if (dictoffset != 0) {
|
||||
PyObject *dict;
|
||||
if (dictoffset < 0) {
|
||||
Py_ssize_t tsize;
|
||||
size_t size;
|
||||
if (dict == NULL) {
|
||||
/* Inline _PyObject_GetDictPtr */
|
||||
dictoffset = tp->tp_dictoffset;
|
||||
if (dictoffset != 0) {
|
||||
if (dictoffset < 0) {
|
||||
Py_ssize_t tsize;
|
||||
size_t size;
|
||||
|
||||
tsize = ((PyVarObject *)obj)->ob_size;
|
||||
if (tsize < 0)
|
||||
tsize = -tsize;
|
||||
size = _PyObject_VAR_SIZE(tp, tsize);
|
||||
tsize = ((PyVarObject *)obj)->ob_size;
|
||||
if (tsize < 0)
|
||||
tsize = -tsize;
|
||||
size = _PyObject_VAR_SIZE(tp, tsize);
|
||||
|
||||
dictoffset += (long)size;
|
||||
assert(dictoffset > 0);
|
||||
assert(dictoffset % SIZEOF_VOID_P == 0);
|
||||
}
|
||||
dictptr = (PyObject **) ((char *)obj + dictoffset);
|
||||
dict = *dictptr;
|
||||
if (dict != NULL) {
|
||||
Py_INCREF(dict);
|
||||
res = PyDict_GetItem(dict, name);
|
||||
if (res != NULL) {
|
||||
Py_INCREF(res);
|
||||
Py_XDECREF(descr);
|
||||
Py_DECREF(dict);
|
||||
goto done;
|
||||
dictoffset += (long)size;
|
||||
assert(dictoffset > 0);
|
||||
assert(dictoffset % SIZEOF_VOID_P == 0);
|
||||
}
|
||||
Py_DECREF(dict);
|
||||
dictptr = (PyObject **) ((char *)obj + dictoffset);
|
||||
dict = *dictptr;
|
||||
}
|
||||
}
|
||||
if (dict != NULL) {
|
||||
Py_INCREF(dict);
|
||||
res = PyDict_GetItem(dict, name);
|
||||
if (res != NULL) {
|
||||
Py_INCREF(res);
|
||||
Py_XDECREF(descr);
|
||||
Py_DECREF(dict);
|
||||
goto done;
|
||||
}
|
||||
Py_DECREF(dict);
|
||||
}
|
||||
|
||||
if (f != NULL) {
|
||||
res = f(descr, obj, (PyObject *)Py_TYPE(obj));
|
||||
|
|
@ -1023,8 +1024,15 @@ PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
|
|||
return res;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyObject_GenericGetAttr(PyObject *obj, PyObject *name)
|
||||
{
|
||||
return _PyObject_GenericGetAttrWithDict(obj, name, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
|
||||
_PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
|
||||
PyObject *value, PyObject *dict)
|
||||
{
|
||||
PyTypeObject *tp = Py_TYPE(obj);
|
||||
PyObject *descr;
|
||||
|
|
@ -1056,27 +1064,29 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
|
|||
}
|
||||
}
|
||||
|
||||
dictptr = _PyObject_GetDictPtr(obj);
|
||||
if (dictptr != NULL) {
|
||||
PyObject *dict = *dictptr;
|
||||
if (dict == NULL && value != NULL) {
|
||||
dict = PyDict_New();
|
||||
if (dict == NULL)
|
||||
goto done;
|
||||
*dictptr = dict;
|
||||
}
|
||||
if (dict != NULL) {
|
||||
Py_INCREF(dict);
|
||||
if (value == NULL)
|
||||
res = PyDict_DelItem(dict, name);
|
||||
else
|
||||
res = PyDict_SetItem(dict, name, value);
|
||||
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
|
||||
PyErr_SetObject(PyExc_AttributeError, name);
|
||||
Py_DECREF(dict);
|
||||
goto done;
|
||||
if (dict == NULL) {
|
||||
dictptr = _PyObject_GetDictPtr(obj);
|
||||
if (dictptr != NULL) {
|
||||
dict = *dictptr;
|
||||
if (dict == NULL && value != NULL) {
|
||||
dict = PyDict_New();
|
||||
if (dict == NULL)
|
||||
goto done;
|
||||
*dictptr = dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dict != NULL) {
|
||||
Py_INCREF(dict);
|
||||
if (value == NULL)
|
||||
res = PyDict_DelItem(dict, name);
|
||||
else
|
||||
res = PyDict_SetItem(dict, name, value);
|
||||
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
|
||||
PyErr_SetObject(PyExc_AttributeError, name);
|
||||
Py_DECREF(dict);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (f != NULL) {
|
||||
res = f(descr, obj, value);
|
||||
|
|
@ -1098,6 +1108,13 @@ PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
|
|||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
PyObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
|
||||
{
|
||||
return _PyObject_GenericSetAttrWithDict(obj, name, value, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Test a value used as condition, e.g., in a for or if statement.
|
||||
Return -1 if an error occurred */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue