[Zope-Checkins] CVS: ZODB3/ZODB - cPickleCache.c:1.72
Jeremy Hylton
jeremy@zope.com
Mon, 31 Mar 2003 17:39:33 -0500
Update of /cvs-repository/ZODB3/ZODB
In directory cvs.zope.org:/tmp/cvs-serv20771
Modified Files:
cPickleCache.c
Log Message:
Fix several ref count bugs.
Remove object_from_oid() which appeared to be mis-used about half the
time. Instead use std PyDict_GetItem() and incref only when
necessary.
Make sure an object's reference to its cache is decref'd when the
object is deallocated. This change seems to eliminate leaking pickle
caches.
Remaining mystery: Why do objects stay in the cache even when there
are no references to them?
=== ZODB3/ZODB/cPickleCache.c 1.71 => 1.72 ===
--- ZODB3/ZODB/cPickleCache.c:1.71 Tue Feb 11 14:16:27 2003
+++ ZODB3/ZODB/cPickleCache.c Mon Mar 31 17:39:33 2003
@@ -147,18 +147,6 @@
/* ---------------------------------------------------------------- */
-/* somewhat of a replacement for PyDict_GetItem(self->data....
- however this returns a *new* reference */
-static PyObject *
-object_from_oid(ccobject *self, PyObject *key)
-{
- PyObject *v = PyDict_GetItem(self->data, key);
- if (!v)
- return NULL;
- Py_INCREF(v);
- return v;
-}
-
#define OBJECT_FROM_RING(SELF, HERE, CTX) \
((cPersistentObject *)(((char *)here) - offsetof(cPersistentObject, ring)))
@@ -308,7 +296,7 @@
static void
_invalidate(ccobject *self, PyObject *key)
{
- PyObject *v = object_from_oid(self, key);
+ PyObject *v = PyDict_GetItem(self->data, key);
if (!v)
return;
@@ -329,7 +317,6 @@
if (PyObject_DelAttr(v, py__p_changed) < 0)
PyErr_Clear();
}
- Py_XDECREF(v);
}
static PyObject *
@@ -374,21 +361,21 @@
static PyObject *
cc_get(ccobject *self, PyObject *args)
{
- PyObject *r, *key, *d = NULL;
+ PyObject *r, *key, *def = NULL;
- if (!PyArg_ParseTuple(args, "O|O:get", &key, &d))
+ if (!PyArg_ParseTuple(args, "O|O:get", &key, &def))
return NULL;
- r = (PyObject *)object_from_oid(self, key);
+ r = PyDict_GetItem(self->data, key);
if (!r) {
- if (d) {
- r = d;
- Py_INCREF(r);
- } else {
+ if (def)
+ r = def;
+ else {
PyErr_SetObject(PyExc_KeyError, key);
return NULL;
}
}
+ Py_INCREF(r);
return r;
}
@@ -501,6 +488,13 @@
interpreter has untracked the reference. Track it again.
*/
_Py_NewReference(v);
+
+ /* Don't increment total refcount as a result of the
+ shenanigans played in this function. The _Py_NewReference()
+ call above and the Py_INCREF() below both create artificial
+ references to v.
+ */
+ _Py_RefTotal -= 2;
/* XXX it may be a problem that v->ob_type is still NULL?
I don't understand what this comment means. --jeremy */
assert(v->ob_type);
@@ -517,6 +511,7 @@
/* XXX Should we call _Py_ForgetReference() on error exit? */
if (PyDict_DelItem(self->data, oid) < 0)
return -1;
+ Py_DECREF((ccobject *)((cPersistentObject *)v)->cache);
if (v->ob_refcnt != 1) {
PyErr_SetString(PyExc_ValueError,
@@ -664,11 +659,12 @@
{
PyObject *r;
- r = (PyObject *)object_from_oid(self, key);
+ r = PyDict_GetItem(self->data, key);
if (r == NULL) {
PyErr_SetObject(PyExc_KeyError, key);
return NULL;
}
+ Py_INCREF(r);
return r;
}
@@ -686,8 +682,8 @@
else if( PyExtensionInstance_Check(v) &&
(((PyExtensionClass*)(v->ob_type))->class_flags & PERSISTENT_TYPE_FLAG) &&
(v->ob_type->tp_basicsize >= sizeof(cPersistentObject)) ) {
- /* Its and instance of a persistent class, (ie Python classeses that
- derive from Persistence.Persistent, BTrees, etc). Thats ok. */
+ /* Its an instance of a persistent class, (ie Python classes that
+ derive from Persistence.Persistent, BTrees, etc). Thats ok. */
}
else {
PyErr_SetString(PyExc_TypeError,
@@ -725,7 +721,7 @@
jar = PyObject_GetAttr(v, py__p_jar);
if (jar == NULL)
return -1;
- if (jar==Py_None) {
+ if (jar == Py_None) {
Py_DECREF(jar);
PyErr_SetString(PyExc_ValueError,
"Cached object jar missing");
@@ -733,16 +729,14 @@
}
Py_DECREF(jar);
- object_again = object_from_oid(self, key);
+ object_again = PyDict_GetItem(self->data, key);
if (object_again) {
if (object_again != v) {
- Py_DECREF(object_again);
PyErr_SetString(PyExc_ValueError,
"Can not re-register object under a different oid");
return -1;
} else {
/* re-register under the same oid - no work needed */
- Py_DECREF(object_again);
return 0;
}
}
@@ -799,7 +793,7 @@
cPersistentObject *p;
/* unlink this item from the ring */
- v = (PyObject *)object_from_oid(self, key);
+ v = PyDict_GetItem(self->data, key);
if (v == NULL)
return -1;
@@ -825,8 +819,6 @@
Py_DECREF((PyObject *)p->cache);
p->cache = NULL;
}
-
- Py_DECREF(v);
if (PyDict_DelItem(self->data, key) < 0) {
PyErr_SetString(PyExc_RuntimeError,